github.com/klaytn/klaytn@v1.12.1/crypto/secp256k1/schnorr_test.go (about) 1 // Copyright 2018 The klaytn Authors 2 // 3 // This file is part of the klaytn library. 4 // 5 // The klaytn library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The klaytn library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the klaytn library. If not, see <http://www.gnu.org/licenses/>. 17 18 package secp256k1 19 20 import ( 21 "bytes" 22 "encoding/hex" 23 "fmt" 24 "testing" 25 "time" 26 ) 27 28 func TestSingle(t *testing.T) { 29 m := hash([]byte("hello world")) 30 31 G := S256() 32 x, _ := hex.DecodeString("4f52e337ad8bf1ce10cbb72ab91d9954474cea39811040df5558297df3e3c1bf") 33 P := G.Marshal(G.ScalarBaseMult(x)) 34 35 R, s := SchnorrSignSingle(G, m, x, P) 36 37 start := time.Now() 38 result := SchnorrVerify(G, m, R, s, P) 39 elapsed := time.Since(start) 40 41 fmt.Printf("Go Imp: %d us\n", elapsed/1000) 42 if !result { 43 t.Fail() 44 } 45 46 start = time.Now() 47 result = SchnorrVerifyNative(m, R, s, P) 48 elapsed = time.Since(start) 49 50 fmt.Printf("C Imp: %d us\n", elapsed/1000) 51 if !result { 52 t.Fail() 53 } 54 } 55 56 func TestDouble(t *testing.T) { 57 msg := hash([]byte("hello")) 58 G := S256() 59 60 // For two arbitrary SECP256k1 private keys 61 x0, _ := hex.DecodeString("4f52e337ad8bf1ce10cbb72ab91d9954474cea39811040df5558297df3e3c1bf") // Alice 62 x1, _ := hex.DecodeString("54390f30fbe7094a5080cd4dcc3f91869faaca23a43aed2eb20a426db067b7c9") // Bob 63 64 // Derive public keys from the private keys; P0 = Alice's pubkey, P1 = Bob's pubkey 65 P0x, P0y := G.ScalarBaseMult(x0) 66 P0 := G.Marshal(P0x, P0y) 67 68 P1x, P1y := G.ScalarBaseMult(x1) 69 P1 := G.Marshal(P1x, P1y) 70 71 // Begin the signing party 72 Q0, R0, y0 := SchnorrSignMultiBootstrap(G, msg, x0, P0, P1) // Alice 73 Q1, R1, y1 := SchnorrSignMultiBootstrap(G, msg, x1, P1, P0) // Bob 74 75 // Unpack the masked public keys 76 Q0x, Q0y := G.Unmarshal(Q0) 77 Q1x, Q1y := G.Unmarshal(Q1) 78 79 // Combine them to get the common public key P 80 P := G.Marshal(G.Add(Q0x, Q0y, Q1x, Q1y)) 81 82 // Unpack R values 83 R0x, R0y := G.Unmarshal(R0) 84 R1x, R1y := G.Unmarshal(R1) 85 86 // Combine them to get the R; this is the first chunk of the signature signed by both Alice and Bob 87 R := G.Marshal(G.Add(R0x, R0y, R1x, R1y)) 88 89 // Now both Alice and Bob know P and R; let's get the rest --- s 90 s0 := SchnorrSignMultiComputeS(msg, P, R, y0) 91 s1 := SchnorrSignMultiComputeS(msg, P, R, y1) 92 93 // Let's combine this together 94 s := ScAdd(s0, s1) 95 96 // At this point, we have (R, s), a complete Schnorr signature signed by both Alice and Bob. 97 // We can verify (R, s) by checking R = s * G + H(m || P || R) * P. 98 99 // Let's verify the signature 100 i := int64(0) 101 var start time.Time 102 var elapsed, sumNative, sumGo time.Duration 103 104 for ; i < 2000; i++ { 105 // Run verification using pure Go impl 106 start = time.Now() 107 108 if !SchnorrVerify(G, msg, R, s, P) { 109 t.Fail() 110 } 111 112 elapsed = time.Since(start) 113 sumGo += elapsed 114 115 // Run verification using native C impl 116 start = time.Now() 117 if !SchnorrVerifyNative(msg, R, s, P) { 118 t.Fail() 119 } 120 121 elapsed = time.Since(start) 122 sumNative += elapsed 123 } 124 125 fmt.Printf("schnorr_go = %d us\n", sumGo.Nanoseconds()/i/1000) 126 fmt.Printf("schnorr_native = %d us\n", sumNative.Nanoseconds()/i/1000) 127 } 128 129 func TestScPointMulTest(t *testing.T) { 130 scalar := hash([]byte("hello")) 131 G := S256() 132 133 P0x, P0y := G.ScalarBaseMult(scalar) 134 P := G.Marshal(P0x, P0y) 135 136 pureGo := G.Marshal(G.ScalarMult(P0x, P0y, scalar)) 137 cImp := ScPointMul(P, scalar) 138 139 if !bytes.Equal(pureGo, cImp) { 140 t.Fail() 141 } 142 } 143 144 func TestScBaseMultTest(t *testing.T) { 145 scalar := hash([]byte("hello")) 146 G := S256() 147 148 pureGo := G.Marshal(G.ScalarBaseMult(scalar)) 149 cImp := ScBaseMul(scalar) 150 151 if !bytes.Equal(pureGo, cImp) { 152 t.Fail() 153 } 154 } 155 156 func TestComputeC(t *testing.T) { 157 G := S256() 158 159 x0, _ := hex.DecodeString("4f52e337ad8bf1ce10cbb72ab91d9954474cea39811040df5558297df3e3c1bf") 160 x1, _ := hex.DecodeString("54390f30fbe7094a5080cd4dcc3f91869faaca23a43aed2eb20a426db067b7c9") 161 162 P0x, P0y := G.ScalarBaseMult(x0) 163 P0 := G.Marshal(P0x, P0y) 164 165 P1x, P1y := G.ScalarBaseMult(x1) 166 P1 := G.Marshal(P1x, P1y) 167 168 C := ComputeC(P0, P1) 169 K := ComputeC(P1, P0) 170 171 if !bytes.Equal(C, K) { 172 t.Fail() 173 } 174 }