Skip to content

Commit

Permalink
[FAB-7396] Use the most recent version of amcl
Browse files Browse the repository at this point in the history
Change-Id: Ia954b9cfb759825df6e47400f3a96780ec3612b2
Signed-off-by: Manu Drijvers <mdr@zurich.ibm.com>
  • Loading branch information
Manu Drijvers committed Dec 8, 2017
1 parent ff0b4fa commit cdb4a98
Show file tree
Hide file tree
Showing 128 changed files with 17,188 additions and 3,940 deletions.
6 changes: 3 additions & 3 deletions common/tools/idemixgen/idemixca/idemixca.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"github.com/hyperledger/fabric/idemix"
"github.com/hyperledger/fabric/msp"
m "github.com/hyperledger/fabric/protos/msp"
amcl "github.com/manudrijvers/amcl/go"
"github.com/milagro-crypto/amcl/version3/go/amcl/FP256BN"
"github.com/pkg/errors"
)

Expand Down Expand Up @@ -44,7 +44,7 @@ func GenerateIssuerKey() ([]byte, []byte, error) {
// (meaning it is used only for verification)
// then only a public key of the CA (issuer) is added to the MSP config (besides the name)
func GenerateSignerConfig(isAdmin bool, ouString string, key *idemix.IssuerKey) ([]byte, error) {
attrs := make([]*amcl.BIG, 2)
attrs := make([]*FP256BN.BIG, 2)

if ouString == "" {
return nil, errors.Errorf("the OU attribute value is empty")
Expand All @@ -57,7 +57,7 @@ func GenerateSignerConfig(isAdmin bool, ouString string, key *idemix.IssuerKey)
}

attrs[0] = idemix.HashModOrder([]byte(ouString))
attrs[1] = amcl.NewBIGint(int(role))
attrs[1] = FP256BN.NewBIGint(int(role))

rng, err := idemix.GetRand()
if err != nil {
Expand Down
28 changes: 15 additions & 13 deletions idemix/credential.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ SPDX-License-Identifier: Apache-2.0
package idemix

import (
amcl "github.com/manudrijvers/amcl/go"
"github.com/milagro-crypto/amcl/version3/go/amcl"
"github.com/milagro-crypto/amcl/version3/go/amcl/FP256BN"
"github.com/pkg/errors"
)

Expand All @@ -33,7 +34,7 @@ import (
// NewCredential issues a new credential, which is the last step of the interactive issuance protocol
// All attribute values are added by the issuer at this step and then signed together with a commitment to
// the user's secret key from a credential request
func NewCredential(key *IssuerKey, m *CredRequest, attrs []*amcl.BIG, rng *amcl.RAND) (*Credential, error) {
func NewCredential(key *IssuerKey, m *CredRequest, attrs []*FP256BN.BIG, rng *amcl.RAND) (*Credential, error) {
// check the credential request that contains
err := m.Check(key.IPk)
if err != nil {
Expand All @@ -49,7 +50,7 @@ func NewCredential(key *IssuerKey, m *CredRequest, attrs []*amcl.BIG, rng *amcl.
E := RandModOrder(rng)
S := RandModOrder(rng)

B := amcl.NewECP()
B := FP256BN.NewECP()
B.Copy(GenG1)
Nym := EcpFromProto(m.Nym)
B.Add(Nym)
Expand All @@ -63,7 +64,7 @@ func NewCredential(key *IssuerKey, m *CredRequest, attrs []*amcl.BIG, rng *amcl.
B.Add(EcpFromProto(key.IPk.HAttrs[len(attrs)-1]).Mul(attrs[len(attrs)-1]))
}

Exp := amcl.Modadd(amcl.FromBytes(key.GetISk()), E, GroupOrder)
Exp := Modadd(FP256BN.FromBytes(key.GetISk()), E, GroupOrder)
Exp.Invmodp(GroupOrder)
A := B.Mul(Exp)

Expand All @@ -81,19 +82,19 @@ func NewCredential(key *IssuerKey, m *CredRequest, attrs []*amcl.BIG, rng *amcl.
}

// Complete completes the credential by updating it with the randomness used to generate CredRequest
func (cred *Credential) Complete(credS1 *amcl.BIG) {
cred.S = BigToBytes(amcl.Modadd(amcl.FromBytes(cred.S), credS1, GroupOrder))
func (cred *Credential) Complete(credS1 *FP256BN.BIG) {
cred.S = BigToBytes(Modadd(FP256BN.FromBytes(cred.S), credS1, GroupOrder))
}

// Ver cryptographically verifies the credential by verifying the signature
// on the attribute values and user's secret key
func (cred *Credential) Ver(sk *amcl.BIG, ipk *IssuerPublicKey) error {
func (cred *Credential) Ver(sk *FP256BN.BIG, ipk *IssuerPublicKey) error {

// parse the credential
A := EcpFromProto(cred.GetA())
B := EcpFromProto(cred.GetB())
E := amcl.FromBytes(cred.GetE())
S := amcl.FromBytes(cred.GetS())
E := FP256BN.FromBytes(cred.GetE())
S := FP256BN.FromBytes(cred.GetS())

// verify that all attribute values are present
for i := 0; i < len(cred.GetAttrs()); i++ {
Expand All @@ -103,23 +104,24 @@ func (cred *Credential) Ver(sk *amcl.BIG, ipk *IssuerPublicKey) error {
}

// verify cryptographic signature on the attributes and the user secret key
BPrime := amcl.NewECP()
BPrime := FP256BN.NewECP()
BPrime.Copy(GenG1)
BPrime.Add(EcpFromProto(ipk.HSk).Mul2(sk, EcpFromProto(ipk.HRand), S))
for i := 0; i < len(cred.Attrs)/2; i++ {
BPrime.Add(EcpFromProto(ipk.HAttrs[2*i]).Mul2(amcl.FromBytes(cred.Attrs[2*i]), EcpFromProto(ipk.HAttrs[2*i+1]), amcl.FromBytes(cred.Attrs[2*i+1])))
BPrime.Add(EcpFromProto(ipk.HAttrs[2*i]).Mul2(FP256BN.FromBytes(cred.Attrs[2*i]), EcpFromProto(ipk.HAttrs[2*i+1]), FP256BN.FromBytes(cred.Attrs[2*i+1])))
}
if len(cred.Attrs)%2 != 0 {
BPrime.Add(EcpFromProto(ipk.HAttrs[len(cred.Attrs)-1]).Mul(amcl.FromBytes(cred.Attrs[len(cred.Attrs)-1])))
BPrime.Add(EcpFromProto(ipk.HAttrs[len(cred.Attrs)-1]).Mul(FP256BN.FromBytes(cred.Attrs[len(cred.Attrs)-1])))
}
if !B.Equals(BPrime) {
return errors.Errorf("b-value from credential does not match the attribute values")
}

a := GenG2.Mul(E)
a.Add(Ecp2FromProto(ipk.W))
a.Affine()

if !amcl.Fexp(amcl.Ate(a, A)).Equals(amcl.Fexp(amcl.Ate(GenG2, B))) {
if !FP256BN.Fexp(FP256BN.Ate(a, A)).Equals(FP256BN.Fexp(FP256BN.Ate(GenG2, B))) {
return errors.Errorf("credential is not cryptographically valid")
}
return nil
Expand Down
19 changes: 10 additions & 9 deletions idemix/credrequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ SPDX-License-Identifier: Apache-2.0
package idemix

import (
amcl "github.com/manudrijvers/amcl/go"
"github.com/milagro-crypto/amcl/version3/go/amcl"
"github.com/milagro-crypto/amcl/version3/go/amcl/FP256BN"
"github.com/pkg/errors"
)

Expand All @@ -30,7 +31,7 @@ const credRequestLabel = "credRequest"
// the signature value, a randomness used to create the signature, the user secret, and the attribute values

// NewCredRequest creates a new Credential Request, the first message of the interactive credential issuance protocol (from user to issuer)
func NewCredRequest(sk *amcl.BIG, credS1 *amcl.BIG, IssuerNonce *amcl.BIG, ipk *IssuerPublicKey, rng *amcl.RAND) *CredRequest {
func NewCredRequest(sk *FP256BN.BIG, credS1 *FP256BN.BIG, IssuerNonce *FP256BN.BIG, ipk *IssuerPublicKey, rng *amcl.RAND) *CredRequest {
HSk := EcpFromProto(ipk.HSk)
HRand := EcpFromProto(ipk.HRand)
Nym := HSk.Mul2(sk, HRand, credS1)
Expand All @@ -55,19 +56,19 @@ func NewCredRequest(sk *amcl.BIG, credS1 *amcl.BIG, IssuerNonce *amcl.BIG, ipk *
copy(proofData[index:], ipk.Hash)

proofC := HashModOrder(proofData)
proofS1 := amcl.Modadd(amcl.Modmul(proofC, sk, GroupOrder), rSk, GroupOrder)
proofS2 := amcl.Modadd(amcl.Modmul(proofC, credS1, GroupOrder), rRand, GroupOrder)
proofS1 := Modadd(FP256BN.Modmul(proofC, sk, GroupOrder), rSk, GroupOrder)
proofS2 := Modadd(FP256BN.Modmul(proofC, credS1, GroupOrder), rRand, GroupOrder)

return &CredRequest{EcpToProto(Nym), BigToBytes(IssuerNonce), BigToBytes(proofC), BigToBytes(proofS1), BigToBytes(proofS2)}
}

// Check cryptographically verifies the credential request
func (m *CredRequest) Check(ipk *IssuerPublicKey) error {
Nym := EcpFromProto(m.GetNym())
IssuerNonce := amcl.FromBytes(m.GetIssuerNonce())
ProofC := amcl.FromBytes(m.GetProofC())
ProofS1 := amcl.FromBytes(m.GetProofS1())
ProofS2 := amcl.FromBytes(m.GetProofS2())
IssuerNonce := FP256BN.FromBytes(m.GetIssuerNonce())
ProofC := FP256BN.FromBytes(m.GetProofC())
ProofS1 := FP256BN.FromBytes(m.GetProofS1())
ProofS2 := FP256BN.FromBytes(m.GetProofS2())

HSk := EcpFromProto(ipk.HSk)
HRand := EcpFromProto(ipk.HRand)
Expand All @@ -93,7 +94,7 @@ func (m *CredRequest) Check(ipk *IssuerPublicKey) error {
index = appendBytesBig(proofData, index, IssuerNonce)
copy(proofData[index:], ipk.Hash)

if !ProofC.Equals(HashModOrder(proofData)) {
if *ProofC != *HashModOrder(proofData) {
return errors.Errorf("zero knowledge proof is invalid")
}

Expand Down
11 changes: 5 additions & 6 deletions idemix/idemix_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,18 @@ SPDX-License-Identifier: Apache-2.0
package idemix

import (
"testing"

"bytes"
"testing"

amcl "github.com/manudrijvers/amcl/go"
"github.com/milagro-crypto/amcl/version3/go/amcl/FP256BN"
"github.com/stretchr/testify/assert"
)

func TestIdemix(t *testing.T) {
AttributeNames := []string{"Attr1", "Attr2", "Attr3", "Attr4", "Attr5"}
attrs := make([]*amcl.BIG, len(AttributeNames))
attrs := make([]*FP256BN.BIG, len(AttributeNames))
for i := range AttributeNames {
attrs[i] = amcl.NewBIGint(i)
attrs[i] = FP256BN.NewBIGint(i)
}

// Test issuer key generation
Expand Down Expand Up @@ -77,7 +76,7 @@ func TestIdemix(t *testing.T) {
assert.NoError(t, cred.Ver(sk, key.IPk), "credential should be valid")

// Issuing a credential with the incorrect amount of attributes should fail
_, err = NewCredential(key, m, []*amcl.BIG{}, rng)
_, err = NewCredential(key, m, []*FP256BN.BIG{}, rng)
assert.Error(t, err, "issuing a credential with the incorrect amount of attributes should fail")

// Breaking the ZK proof of the CredRequest should make it invalid
Expand Down
17 changes: 9 additions & 8 deletions idemix/issuerkey.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ package idemix

import (
"github.com/golang/protobuf/proto"
amcl "github.com/manudrijvers/amcl/go"
"github.com/milagro-crypto/amcl/version3/go/amcl"
"github.com/milagro-crypto/amcl/version3/go/amcl/FP256BN"
"github.com/pkg/errors"
)

Expand Down Expand Up @@ -81,7 +82,7 @@ func NewIssuerKey(AttributeNames []string, rng *amcl.RAND) (*IssuerKey, error) {
proofC := HashModOrder(proofData)
key.IPk.ProofC = BigToBytes(proofC)

proofS := amcl.Modadd(amcl.Modmul(proofC, ISk, GroupOrder), r, GroupOrder)
proofS := Modadd(FP256BN.Modmul(proofC, ISk, GroupOrder), r, GroupOrder)
key.IPk.ProofS = BigToBytes(proofS)

serializedIPk, err := proto.Marshal(key.IPk)
Expand All @@ -99,15 +100,15 @@ func (IPk *IssuerPublicKey) Check() error {
NumAttrs := len(IPk.GetAttributeNames())
HSk := EcpFromProto(IPk.GetHSk())
HRand := EcpFromProto(IPk.GetHRand())
HAttrs := make([]*amcl.ECP, len(IPk.GetHAttrs()))
HAttrs := make([]*FP256BN.ECP, len(IPk.GetHAttrs()))
for i := 0; i < len(IPk.GetHAttrs()); i++ {
HAttrs[i] = EcpFromProto(IPk.GetHAttrs()[i])
}
BarG1 := EcpFromProto(IPk.GetBarG1())
BarG2 := EcpFromProto(IPk.GetBarG2())
W := Ecp2FromProto(IPk.GetW())
ProofC := amcl.FromBytes(IPk.GetProofC())
ProofS := amcl.FromBytes(IPk.GetProofS())
ProofC := FP256BN.FromBytes(IPk.GetProofC())
ProofS := FP256BN.FromBytes(IPk.GetProofS())

if NumAttrs < 0 ||
HSk == nil ||
Expand All @@ -130,9 +131,9 @@ func (IPk *IssuerPublicKey) Check() error {
index := 0

t1 := GenG2.Mul(ProofS)
t1.Add(W.Mul(amcl.Modneg(ProofC, GroupOrder)))
t1.Add(W.Mul(FP256BN.Modneg(ProofC, GroupOrder)))
t2 := BarG1.Mul(ProofS)
t2.Add(BarG2.Mul(amcl.Modneg(ProofC, GroupOrder)))
t2.Add(BarG2.Mul(FP256BN.Modneg(ProofC, GroupOrder)))

index = appendBytesG2(proofData, index, t1)
index = appendBytesG1(proofData, index, t2)
Expand All @@ -141,7 +142,7 @@ func (IPk *IssuerPublicKey) Check() error {
index = appendBytesG2(proofData, index, W)
index = appendBytesG1(proofData, index, BarG2)

if !ProofC.Equals(HashModOrder(proofData)) {
if *ProofC != *HashModOrder(proofData) {
return errors.Errorf("zero knowledge proof in public key invalid")
}

Expand Down
21 changes: 11 additions & 10 deletions idemix/nymsignature.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ SPDX-License-Identifier: Apache-2.0
package idemix

import (
amcl "github.com/manudrijvers/amcl/go"
"github.com/milagro-crypto/amcl/version3/go/amcl"
"github.com/milagro-crypto/amcl/version3/go/amcl/FP256BN"
"github.com/pkg/errors"
)

// NewSignature creates a new idemix pseudonym signature
func NewNymSignature(sk *amcl.BIG, Nym *amcl.ECP, RNym *amcl.BIG, ipk *IssuerPublicKey, msg []byte, rng *amcl.RAND) (*NymSignature, error) {
func NewNymSignature(sk *FP256BN.BIG, Nym *FP256BN.ECP, RNym *FP256BN.BIG, ipk *IssuerPublicKey, msg []byte, rng *amcl.RAND) (*NymSignature, error) {
if sk == nil || Nym == nil || RNym == nil || ipk == nil || rng == nil {
return nil, errors.Errorf("cannot create NymSignature: received nil input")
}
Expand Down Expand Up @@ -57,8 +58,8 @@ func NewNymSignature(sk *amcl.BIG, Nym *amcl.ECP, RNym *amcl.BIG, ipk *IssuerPub
ProofC := HashModOrder(proofData)

// Finally, we compute the s-values, which form the response answering challenge c
ProofSSk := amcl.Modadd(rSk, amcl.Modmul(ProofC, sk, GroupOrder), GroupOrder)
ProofSRNym := amcl.Modadd(rRNym, amcl.Modmul(ProofC, RNym, GroupOrder), GroupOrder)
ProofSSk := Modadd(rSk, FP256BN.Modmul(ProofC, sk, GroupOrder), GroupOrder)
ProofSRNym := Modadd(rRNym, FP256BN.Modmul(ProofC, RNym, GroupOrder), GroupOrder)

// The signature consists of the Fiat-Shamir hash (ProofC), the s-values (ProofSSk, ProofSRNym), and the nonce.
return &NymSignature{
Expand All @@ -69,12 +70,12 @@ func NewNymSignature(sk *amcl.BIG, Nym *amcl.ECP, RNym *amcl.BIG, ipk *IssuerPub
}

// Ver verifies an idemix NymSignature
func (sig *NymSignature) Ver(nym *amcl.ECP, ipk *IssuerPublicKey, msg []byte) error {
ProofC := amcl.FromBytes(sig.GetProofC())
ProofSSk := amcl.FromBytes(sig.GetProofSSk())
ProofSRNym := amcl.FromBytes(sig.GetProofSRNym())
func (sig *NymSignature) Ver(nym *FP256BN.ECP, ipk *IssuerPublicKey, msg []byte) error {
ProofC := FP256BN.FromBytes(sig.GetProofC())
ProofSSk := FP256BN.FromBytes(sig.GetProofSSk())
ProofSRNym := FP256BN.FromBytes(sig.GetProofSRNym())

Nonce := amcl.FromBytes(sig.GetNonce())
Nonce := FP256BN.FromBytes(sig.GetNonce())

HRand := EcpFromProto(ipk.HRand)
HSk := EcpFromProto(ipk.HSk)
Expand Down Expand Up @@ -102,7 +103,7 @@ func (sig *NymSignature) Ver(nym *amcl.ECP, ipk *IssuerPublicKey, msg []byte) er
proofData = proofData[:2*FieldBytes]
index = appendBytesBig(proofData, index, c)
index = appendBytesBig(proofData, index, Nonce)
if !ProofC.Equals(HashModOrder(proofData)) {
if *ProofC != *HashModOrder(proofData) {
return errors.Errorf("pseudonym signature invalid: zero-knowledge proof is invalid")
}

Expand Down
Loading

0 comments on commit cdb4a98

Please sign in to comment.