github.com/Hnampk/my-fabric@v0.0.0-20201028083322-75069da399c0/idemix/util.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package idemix 8 9 import ( 10 "crypto/rand" 11 "crypto/sha256" 12 13 "github.com/hyperledger/fabric-amcl/amcl" 14 "github.com/hyperledger/fabric-amcl/amcl/FP256BN" 15 "github.com/pkg/errors" 16 ) 17 18 // GenG1 is a generator of Group G1 19 var GenG1 = FP256BN.NewECPbigs( 20 FP256BN.NewBIGints(FP256BN.CURVE_Gx), 21 FP256BN.NewBIGints(FP256BN.CURVE_Gy)) 22 23 // GenG2 is a generator of Group G2 24 var GenG2 = FP256BN.NewECP2fp2s( 25 FP256BN.NewFP2bigs(FP256BN.NewBIGints(FP256BN.CURVE_Pxa), FP256BN.NewBIGints(FP256BN.CURVE_Pxb)), 26 FP256BN.NewFP2bigs(FP256BN.NewBIGints(FP256BN.CURVE_Pya), FP256BN.NewBIGints(FP256BN.CURVE_Pyb))) 27 28 // GenGT is a generator of Group GT 29 var GenGT = FP256BN.Fexp(FP256BN.Ate(GenG2, GenG1)) 30 31 // GroupOrder is the order of the groups 32 var GroupOrder = FP256BN.NewBIGints(FP256BN.CURVE_Order) 33 34 // FieldBytes is the bytelength of the group order 35 var FieldBytes = int(FP256BN.MODBYTES) 36 37 // RandModOrder returns a random element in 0, ..., GroupOrder-1 38 func RandModOrder(rng *amcl.RAND) *FP256BN.BIG { 39 // curve order q 40 q := FP256BN.NewBIGints(FP256BN.CURVE_Order) 41 42 // Take random element in Zq 43 return FP256BN.Randomnum(q, rng) 44 } 45 46 // HashModOrder hashes data into 0, ..., GroupOrder-1 47 func HashModOrder(data []byte) *FP256BN.BIG { 48 digest := sha256.Sum256(data) 49 digestBig := FP256BN.FromBytes(digest[:]) 50 digestBig.Mod(GroupOrder) 51 return digestBig 52 } 53 54 func appendBytes(data []byte, index int, bytesToAdd []byte) int { 55 copy(data[index:], bytesToAdd) 56 return index + len(bytesToAdd) 57 } 58 func appendBytesG1(data []byte, index int, E *FP256BN.ECP) int { 59 length := 2*FieldBytes + 1 60 E.ToBytes(data[index:index+length], false) 61 return index + length 62 } 63 func EcpToBytes(E *FP256BN.ECP) []byte { 64 length := 2*FieldBytes + 1 65 res := make([]byte, length) 66 E.ToBytes(res, false) 67 return res 68 } 69 func appendBytesG2(data []byte, index int, E *FP256BN.ECP2) int { 70 length := 4 * FieldBytes 71 E.ToBytes(data[index : index+length]) 72 return index + length 73 } 74 func appendBytesBig(data []byte, index int, B *FP256BN.BIG) int { 75 length := FieldBytes 76 B.ToBytes(data[index : index+length]) 77 return index + length 78 } 79 func appendBytesString(data []byte, index int, s string) int { 80 bytes := []byte(s) 81 copy(data[index:], bytes) 82 return index + len(bytes) 83 } 84 85 // MakeNym creates a new unlinkable pseudonym 86 func MakeNym(sk *FP256BN.BIG, IPk *IssuerPublicKey, rng *amcl.RAND) (*FP256BN.ECP, *FP256BN.BIG) { 87 // Construct a commitment to the sk 88 // Nym = h_{sk}^sk \cdot h_r^r 89 RandNym := RandModOrder(rng) 90 Nym := EcpFromProto(IPk.HSk).Mul2(sk, EcpFromProto(IPk.HRand), RandNym) 91 return Nym, RandNym 92 } 93 94 // BigToBytes takes an *amcl.BIG and returns a []byte representation 95 func BigToBytes(big *FP256BN.BIG) []byte { 96 ret := make([]byte, FieldBytes) 97 big.ToBytes(ret) 98 return ret 99 } 100 101 // EcpToProto converts a *amcl.ECP into the proto struct *ECP 102 func EcpToProto(p *FP256BN.ECP) *ECP { 103 return &ECP{ 104 X: BigToBytes(p.GetX()), 105 Y: BigToBytes(p.GetY())} 106 } 107 108 // EcpFromProto converts a proto struct *ECP into an *amcl.ECP 109 func EcpFromProto(p *ECP) *FP256BN.ECP { 110 return FP256BN.NewECPbigs(FP256BN.FromBytes(p.GetX()), FP256BN.FromBytes(p.GetY())) 111 } 112 113 // Ecp2ToProto converts a *amcl.ECP2 into the proto struct *ECP2 114 func Ecp2ToProto(p *FP256BN.ECP2) *ECP2 { 115 return &ECP2{ 116 Xa: BigToBytes(p.GetX().GetA()), 117 Xb: BigToBytes(p.GetX().GetB()), 118 Ya: BigToBytes(p.GetY().GetA()), 119 Yb: BigToBytes(p.GetY().GetB())} 120 } 121 122 // Ecp2FromProto converts a proto struct *ECP2 into an *amcl.ECP2 123 func Ecp2FromProto(p *ECP2) *FP256BN.ECP2 { 124 return FP256BN.NewECP2fp2s( 125 FP256BN.NewFP2bigs(FP256BN.FromBytes(p.GetXa()), FP256BN.FromBytes(p.GetXb())), 126 FP256BN.NewFP2bigs(FP256BN.FromBytes(p.GetYa()), FP256BN.FromBytes(p.GetYb()))) 127 } 128 129 // GetRand returns a new *amcl.RAND with a fresh seed 130 func GetRand() (*amcl.RAND, error) { 131 seedLength := 32 132 b := make([]byte, seedLength) 133 _, err := rand.Read(b) 134 if err != nil { 135 return nil, errors.Wrap(err, "error getting randomness for seed") 136 } 137 rng := amcl.NewRAND() 138 rng.Clean() 139 rng.Seed(seedLength, b) 140 return rng, nil 141 } 142 143 // Modadd takes input BIGs a, b, m, and returns a+b modulo m 144 func Modadd(a, b, m *FP256BN.BIG) *FP256BN.BIG { 145 c := a.Plus(b) 146 c.Mod(m) 147 return c 148 } 149 150 // Modsub takes input BIGs a, b, m and returns a-b modulo m 151 func Modsub(a, b, m *FP256BN.BIG) *FP256BN.BIG { 152 return Modadd(a, FP256BN.Modneg(b, m), m) 153 }