github.com/incognitochain/go-incognito-sdk@v1.0.1/privacy/schnorr.go (about) 1 package privacy 2 3 import ( 4 "crypto/subtle" 5 "errors" 6 "github.com/incognitochain/go-incognito-sdk/common" 7 ) 8 9 // SchnorrPublicKey represents Schnorr Publickey 10 // PK = G^SK + H^R 11 type SchnorrPublicKey struct { 12 publicKey *Point 13 g, h *Point 14 } 15 16 func (schnorrPubKey SchnorrPublicKey) GetPublicKey() *Point { 17 return schnorrPubKey.publicKey 18 } 19 20 // SchnorrPrivateKey represents Schnorr Privatekey 21 type SchnorrPrivateKey struct { 22 privateKey *Scalar 23 randomness *Scalar 24 publicKey *SchnorrPublicKey 25 } 26 27 func (schnPrivKey SchnorrPrivateKey) GetPublicKey() *SchnorrPublicKey { 28 return schnPrivKey.publicKey 29 } 30 31 // SchnSignature represents Schnorr Signature 32 type SchnSignature struct { 33 e, z1, z2 *Scalar 34 } 35 36 // Set sets Schnorr private key 37 func (privateKey *SchnorrPrivateKey) Set(sk *Scalar, r *Scalar) { 38 privateKey.privateKey = sk 39 privateKey.randomness = r 40 privateKey.publicKey = new(SchnorrPublicKey) 41 privateKey.publicKey.g, _ = new(Point).SetKey(&PedCom.G[PedersenPrivateKeyIndex].key) 42 privateKey.publicKey.h, _ = new(Point).SetKey(&PedCom.G[PedersenRandomnessIndex].key) 43 privateKey.publicKey.publicKey = new(Point).ScalarMult(PedCom.G[PedersenPrivateKeyIndex], sk) 44 privateKey.publicKey.publicKey.Add(privateKey.publicKey.publicKey, new(Point).ScalarMult(PedCom.G[PedersenRandomnessIndex], r)) 45 } 46 47 // Set sets Schnorr public key 48 func (publicKey *SchnorrPublicKey) Set(pk *Point) { 49 publicKey.publicKey, _ = new(Point).SetKey(&pk.key) 50 51 publicKey.g, _ = new(Point).SetKey(&PedCom.G[PedersenPrivateKeyIndex].key) 52 publicKey.h, _ = new(Point).SetKey(&PedCom.G[PedersenRandomnessIndex].key) 53 } 54 55 //Sign is function which using for signing on hash array by private key 56 func (privateKey SchnorrPrivateKey) Sign(data []byte) (*SchnSignature, error) { 57 if len(data) != common.HashSize { 58 return nil, NewPrivacyErr(UnexpectedErr, errors.New("hash length must be 32 bytes")) 59 } 60 61 signature := new(SchnSignature) 62 63 // has privacy 64 if !privateKey.randomness.IsZero() { 65 // generates random numbers s1, s2 in [0, Curve.Params().N - 1] 66 67 s1 := RandomScalar() 68 s2 := RandomScalar() 69 70 // t = s1*G + s2*H 71 t := new(Point).ScalarMult(privateKey.publicKey.g, s1) 72 t.Add(t, new(Point).ScalarMult(privateKey.publicKey.h, s2)) 73 74 // E is the hash of elliptic point t and data need to be signed 75 msg := append(t.ToBytesS(), data...) 76 77 signature.e = HashToScalar(msg) 78 79 signature.z1 = new(Scalar).Mul(privateKey.privateKey, signature.e) 80 signature.z1 = new(Scalar).Sub(s1, signature.z1) 81 82 signature.z2 = new(Scalar).Mul(privateKey.randomness, signature.e) 83 signature.z2 = new(Scalar).Sub(s2, signature.z2) 84 85 return signature, nil 86 } 87 88 // generates random numbers s, k2 in [0, Curve.Params().N - 1] 89 s := RandomScalar() 90 91 // t = s*G 92 t := new(Point).ScalarMult(privateKey.publicKey.g, s) 93 94 // E is the hash of elliptic point t and data need to be signed 95 msg := append(t.ToBytesS(), data...) 96 signature.e = HashToScalar(msg) 97 98 // Z1 = s - e*sk 99 signature.z1 = new(Scalar).Mul(privateKey.privateKey, signature.e) 100 signature.z1 = new(Scalar).Sub(s, signature.z1) 101 102 signature.z2 = nil 103 104 return signature, nil 105 } 106 107 //Verify is function which using for verify that the given signature was signed by by privatekey of the public key 108 func (publicKey SchnorrPublicKey) Verify(signature *SchnSignature, data []byte) bool { 109 if signature == nil { 110 return false 111 } 112 rv := new(Point).ScalarMult(publicKey.publicKey, signature.e) 113 rv.Add(rv, new(Point).ScalarMult(publicKey.g, signature.z1)) 114 if signature.z2 != nil { 115 rv.Add(rv, new(Point).ScalarMult(publicKey.h, signature.z2)) 116 } 117 msg := append(rv.ToBytesS(), data...) 118 119 ev := HashToScalar(msg) 120 return subtle.ConstantTimeCompare(ev.ToBytesS(), signature.e.ToBytesS()) == 1 121 } 122 123 func (sig SchnSignature) Bytes() []byte { 124 bytes := append(sig.e.ToBytesS(), sig.z1.ToBytesS()...) 125 // Z2 is nil when has no privacy 126 if sig.z2 != nil { 127 bytes = append(bytes, sig.z2.ToBytesS()...) 128 } 129 return bytes 130 } 131 132 func (sig *SchnSignature) SetBytes(bytes []byte) error { 133 if len(bytes) == 0 { 134 return NewPrivacyErr(InvalidInputToSetBytesErr, nil) 135 } 136 sig.e = new(Scalar).FromBytesS(bytes[0:Ed25519KeySize]) 137 sig.z1 = new(Scalar).FromBytesS(bytes[Ed25519KeySize : 2*Ed25519KeySize]) 138 if len(bytes) == 3*Ed25519KeySize { 139 sig.z2 = new(Scalar).FromBytesS(bytes[2*Ed25519KeySize:]) 140 } else { 141 sig.z2 = nil 142 } 143 144 return nil 145 }