1
2
3
4
5 package fipstest
6
7 import (
8 "bytes"
9 "crypto/elliptic"
10 "internal/byteorder"
11 "math/big"
12 "testing"
13 )
14
15 func bytesToLimbs(b []byte) [4]uint64 {
16 var l [4]uint64
17 l[0] = byteorder.BEUint64(b[24:])
18 l[1] = byteorder.BEUint64(b[16:])
19 l[2] = byteorder.BEUint64(b[8:])
20 l[3] = byteorder.BEUint64(b[:])
21 return l
22 }
23
24 func limbsToBytes(l [4]uint64) []byte {
25 b := make([]byte, 32)
26 byteorder.BEPutUint64(b[24:], l[0])
27 byteorder.BEPutUint64(b[16:], l[1])
28 byteorder.BEPutUint64(b[8:], l[2])
29 byteorder.BEPutUint64(b[:], l[3])
30 return b
31 }
32
33 func TestP256OrdInverse(t *testing.T) {
34 N := elliptic.P256().Params().N
35
36
37 zero := make([]byte, 32)
38 k := bytesToLimbs(zero)
39 p256OrdInverse(t, &k)
40 if !bytes.Equal(limbsToBytes(k), zero) {
41 t.Error("unexpected output for inv(0)")
42 }
43
44
45 input := make([]byte, 32)
46 N.FillBytes(input)
47 k = bytesToLimbs(input)
48 p256OrdInverse(t, &k)
49 if !bytes.Equal(limbsToBytes(k), zero) {
50 t.Error("unexpected output for inv(N)")
51 }
52
53
54 exp := new(big.Int).ModInverse(big.NewInt(1), N).FillBytes(make([]byte, 32))
55 big.NewInt(1).FillBytes(input)
56 k = bytesToLimbs(input)
57 p256OrdInverse(t, &k)
58 if !bytes.Equal(limbsToBytes(k), exp) {
59 t.Error("unexpected output for inv(1)")
60 }
61
62 new(big.Int).Add(N, big.NewInt(1)).FillBytes(input)
63 k = bytesToLimbs(input)
64 p256OrdInverse(t, &k)
65 if !bytes.Equal(limbsToBytes(k), exp) {
66 t.Error("unexpected output for inv(N+1)")
67 }
68
69
70 exp = new(big.Int).ModInverse(big.NewInt(20), N).FillBytes(make([]byte, 32))
71 big.NewInt(20).FillBytes(input)
72 k = bytesToLimbs(input)
73 p256OrdInverse(t, &k)
74 if !bytes.Equal(limbsToBytes(k), exp) {
75 t.Error("unexpected output for inv(20)")
76 }
77
78 new(big.Int).Add(N, big.NewInt(20)).FillBytes(input)
79 k = bytesToLimbs(input)
80 p256OrdInverse(t, &k)
81 if !bytes.Equal(limbsToBytes(k), exp) {
82 t.Error("unexpected output for inv(N+20)")
83 }
84
85
86 bigInput := new(big.Int).Lsh(big.NewInt(1), 256)
87 bigInput.Sub(bigInput, big.NewInt(1))
88 exp = new(big.Int).ModInverse(bigInput, N).FillBytes(make([]byte, 32))
89 bigInput.FillBytes(input)
90 k = bytesToLimbs(input)
91 p256OrdInverse(t, &k)
92 if !bytes.Equal(limbsToBytes(k), exp) {
93 t.Error("unexpected output for inv(2^256-1)")
94 }
95 }
96
View as plain text