github.com/cloudflare/circl@v1.5.0/dh/x448/key_test.go (about) 1 package x448 2 3 import ( 4 "crypto/rand" 5 "encoding/hex" 6 "encoding/json" 7 "flag" 8 "fmt" 9 "io" 10 "os" 11 "testing" 12 13 "github.com/cloudflare/circl/internal/test" 14 ) 15 16 func hexStr2Key(k *Key, s string) { 17 b, err := hex.DecodeString(s) 18 if err != nil { 19 panic("Can't convert string to key") 20 } 21 copy(k[:], b) 22 } 23 24 // Indicates whether long tests should be run 25 var runLongTest = flag.Bool("long", false, "runs longer tests") 26 27 type katVector struct { 28 Public string `json:"input"` 29 Shared string `json:"output"` 30 Private string `json:"scalar"` 31 } 32 33 func TestRFC7748Kat(t *testing.T) { 34 const nameFile = "testdata/rfc7748_kat_test.json" 35 var kat []katVector 36 37 jsonFile, err := os.Open(nameFile) 38 if err != nil { 39 t.Fatalf("File %v can not be opened. Error: %v", nameFile, err) 40 } 41 defer jsonFile.Close() 42 input, err := io.ReadAll(jsonFile) 43 if err != nil { 44 t.Fatalf("File %v can not be read. Error: %v", nameFile, err) 45 } 46 47 err = json.Unmarshal(input, &kat) 48 if err != nil { 49 t.Fatalf("File %v can not be loaded. Error: %v", nameFile, err) 50 } 51 var priv, pub, got, want Key 52 for _, v := range kat { 53 hexStr2Key(&pub, v.Public) 54 hexStr2Key(&priv, v.Private) 55 Shared(&got, &priv, &pub) 56 hexStr2Key(&want, v.Shared) 57 if got != want { 58 test.ReportError(t, got, want, v) 59 } 60 } 61 } 62 63 type katTimes struct { 64 Times uint32 `json:"times"` 65 Key string `json:"key"` 66 } 67 68 func TestRFC7748Times(t *testing.T) { 69 const nameFile = "testdata/rfc7748_times_test.json" 70 jsonFile, err := os.Open(nameFile) 71 if err != nil { 72 t.Fatalf("File %v can not be opened. Error: %v", nameFile, err) 73 } 74 defer jsonFile.Close() 75 input, err := io.ReadAll(jsonFile) 76 if err != nil { 77 t.Fatalf("File %v can not be read. Error: %v", nameFile, err) 78 } 79 80 var kat []katTimes 81 err = json.Unmarshal(input, &kat) 82 if err != nil { 83 t.Fatalf("File %v can not be loaded. Error: %v", nameFile, err) 84 } 85 var got, want Key 86 for _, v := range kat { 87 if !*runLongTest && v.Times == uint32(1000000) { 88 t.Log("Skipped one long test, add -long flag to run longer tests") 89 continue 90 } 91 u := Key{5} 92 k := u 93 r := u 94 for i := uint32(0); i < v.Times; i++ { 95 Shared(&r, &k, &u) 96 u = k 97 k = r 98 } 99 got = k 100 hexStr2Key(&want, v.Key) 101 102 if got != want { 103 test.ReportError(t, got, want, v.Times) 104 } 105 } 106 } 107 108 func TestBase(t *testing.T) { 109 testTimes := 1 << 10 110 var got, want, secret Key 111 gen := Key{5} 112 for i := 0; i < testTimes; i++ { 113 _, _ = io.ReadFull(rand.Reader, secret[:]) 114 KeyGen(&got, &secret) 115 Shared(&want, &secret, &gen) 116 if got != want { 117 test.ReportError(t, got, want, secret) 118 } 119 } 120 } 121 122 func BenchmarkX448(b *testing.B) { 123 var x, y, z Key 124 _, _ = io.ReadFull(rand.Reader, x[:]) 125 _, _ = io.ReadFull(rand.Reader, y[:]) 126 _, _ = io.ReadFull(rand.Reader, z[:]) 127 128 b.Run("KeyGen", func(b *testing.B) { 129 for i := 0; i < b.N; i++ { 130 KeyGen(&x, &y) 131 } 132 }) 133 b.Run("Shared", func(b *testing.B) { 134 for i := 0; i < b.N; i++ { 135 Shared(&z, &x, &y) 136 } 137 }) 138 } 139 140 func Example_x448() { 141 var AliceSecret, BobSecret, 142 AlicePublic, BobPublic, 143 AliceShared, BobShared Key 144 145 // Generating Alice's secret and public keys 146 _, _ = io.ReadFull(rand.Reader, AliceSecret[:]) 147 KeyGen(&AlicePublic, &AliceSecret) 148 149 // Generating Bob's secret and public keys 150 _, _ = io.ReadFull(rand.Reader, BobSecret[:]) 151 KeyGen(&BobPublic, &BobSecret) 152 153 // Deriving Alice's shared key 154 okA := Shared(&AliceShared, &AliceSecret, &BobPublic) 155 156 // Deriving Bob's shared key 157 okB := Shared(&BobShared, &BobSecret, &AlicePublic) 158 159 fmt.Println(AliceShared == BobShared && okA && okB) 160 // Output: true 161 }