├── rand ├── cpu_amd64.go ├── README.md ├── cpu.go ├── cpu_amd64.s ├── laplace.go ├── LICENSE ├── salsa20rand_test.go └── salsa20rand.go ├── bn256 ├── .clang-format ├── final_expo.h ├── mydouble.c ├── mul.h ├── mydouble.h ├── optate.h ├── linefunction.h ├── scalar.h ├── gfp.go ├── int_test.go ├── hash_test.go ├── twistpoint_fp2.h ├── gfp12.go ├── consts.s ├── curvepoint_fp.h ├── scalar.c ├── fp6e.h ├── gfp2.go ├── curve.go ├── hash.go ├── fpe.h ├── twist.go ├── scalar_sub_nored.s ├── LICENSE ├── convert.go ├── fp12e.h ├── gfp2_test.go ├── optate.c ├── final_expo.c ├── parameters.c ├── parameters.h ├── mul.c ├── fp2e.h ├── linefunction.c ├── checkdouble.h ├── bn256_test.go ├── fpe.c ├── fp2e_triple2.s ├── fp2e_neg2.s └── fp2e_double2.s ├── go.mod ├── README.md ├── go.sum ├── shuffle ├── shuffle_test.go ├── LICENSE └── shuffle.go ├── bn256ref ├── example_test.go ├── LICENSE ├── constants.go ├── hash.go ├── gfp12.go ├── gfp2.go ├── twist.go ├── curve.go ├── gfp6.go └── hash_test.go ├── onionbox ├── onion.go └── LICENSE ├── bls ├── LICENSE ├── bls_test.go └── bls.go └── ibe ├── LICENSE ├── ibe.go └── ibe_test.go /rand/cpu_amd64.go: -------------------------------------------------------------------------------- 1 | package rand 2 | 3 | func cpu() uint64 4 | -------------------------------------------------------------------------------- /rand/README.md: -------------------------------------------------------------------------------- 1 | `cpu*` code from https://github.com/jonhoo/drwmutex 2 | -------------------------------------------------------------------------------- /bn256/.clang-format: -------------------------------------------------------------------------------- 1 | Language: Cpp 2 | BasedOnStyle: LLVM 3 | 4 | ColumnLimit: 0 5 | UseTab: ForIndentation 6 | IndentWidth: 8 7 | 8 | BreakBeforeBraces: Linux 9 | ReflowComments: false 10 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module vuvuzela.io/crypto 2 | 3 | go 1.18 4 | 5 | require golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898 6 | 7 | require golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 // indirect 8 | -------------------------------------------------------------------------------- /bn256/final_expo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: dclxvi-20130329/final_expo.h 3 | * Author: Ruben Niederhagen, Peter Schwabe 4 | * Public Domain 5 | */ 6 | 7 | #ifndef FINAL_EXPO_H 8 | #define FINAL_EXPO_H 9 | 10 | #include "fp12e.h" 11 | 12 | void final_expo(fp12e_t rop); 13 | 14 | #endif // ifdef FINAL_EXPO_H 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This repository holds cryptography libraries created for 2 | [Vuvuzela](https://github.com/vuvuzela/vuvuzela) and 3 | [Alpenhorn](https://github.com/vuvuzela/alpenhorn). 4 | **Proceed with caution**: these libraries are experimental and have 5 | not been proven correct. 6 | 7 | Documentation: https://godoc.org/vuvuzela.io/crypto 8 | -------------------------------------------------------------------------------- /rand/cpu.go: -------------------------------------------------------------------------------- 1 | // +build !amd64 2 | 3 | package rand 4 | 5 | // cpu returns a unique identifier for the core the current goroutine is 6 | // executing on. This function is platform dependent, and is implemented in 7 | // cpu_*.s. 8 | func cpu() uint64 { 9 | // this reverts the behaviour to that of a regular DRWMutex 10 | return 0 11 | } 12 | -------------------------------------------------------------------------------- /bn256/mydouble.c: -------------------------------------------------------------------------------- 1 | /* 2 | * File: dclxvi-20130329/mydouble.c 3 | * Author: Ruben Niederhagen, Peter Schwabe 4 | * Public Domain 5 | */ 6 | 7 | #include "mydouble.h" 8 | 9 | #ifndef CHECK 10 | #include 11 | 12 | double remround(double a, double d) 13 | { 14 | double carry = round(a / d); 15 | return a - carry * d; 16 | } 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /bn256/mul.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: dclxvi-20130329/mul.h 3 | * Author: Ruben Niederhagen, Peter Schwabe 4 | * Public Domain 5 | */ 6 | 7 | #ifndef MUL_H 8 | #define MUL_H 9 | 10 | #include "mydouble.h" 11 | 12 | void polymul(mydouble *h, const mydouble *f, const mydouble *g); 13 | void degred(mydouble *h); 14 | void coeffred_round_par(mydouble *h); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /rand/cpu_amd64.s: -------------------------------------------------------------------------------- 1 | #include "textflag.h" 2 | 3 | // func cpu() uint64 4 | TEXT ·cpu(SB),NOSPLIT,$0-8 5 | MOVL $0x01, AX // version information 6 | MOVL $0x00, BX // any leaf will do 7 | MOVL $0x00, CX // any subleaf will do 8 | 9 | // call CPUID 10 | BYTE $0x0f 11 | BYTE $0xa2 12 | 13 | SHRQ $24, BX // logical cpu id is put in EBX[31-24] 14 | MOVQ BX, ret+0(FP) 15 | RET 16 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898 h1:SLP7Q4Di66FONjDJbCYrCRrh97focO6sLogHO7/g8F0= 2 | golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 3 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4= 4 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 5 | -------------------------------------------------------------------------------- /bn256/mydouble.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: dclxvi-20130329/mydouble.h 3 | * Author: Ruben Niederhagen, Peter Schwabe 4 | * Public Domain 5 | */ 6 | 7 | #ifndef MYDOUBLE_H 8 | #define MYDOUBLE_H 9 | 10 | #ifdef CHECK 11 | #include "checkdouble.h" 12 | #define mydouble CheckDouble 13 | #else 14 | #define mydouble double 15 | #define setmax(x, y) 16 | #define todouble(x) x 17 | double remround(double a, double d); 18 | #endif 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /bn256/optate.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: dclxvi-20130329/optate.h 3 | * Author: Ruben Niederhagen, Peter Schwabe 4 | * Public Domain 5 | */ 6 | 7 | #ifndef OPTATE_H 8 | #define OPTATE_H 9 | 10 | #include "curvepoint_fp.h" 11 | #include "fp12e.h" 12 | #include "twistpoint_fp2.h" 13 | 14 | void optate(fp12e_t rop, const twistpoint_fp2_t op1, const curvepoint_fp_t op2); 15 | void optate_miller(fp12e_t rop, const twistpoint_fp2_t op1, const curvepoint_fp_t op2); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /bn256/linefunction.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: dclxvi-20130329/linefunction.h 3 | * Author: Ruben Niederhagen, Peter Schwabe 4 | * Public Domain 5 | */ 6 | 7 | #ifndef LINEFUNCTION_H 8 | #define LINEFUNCTION_H 9 | 10 | #include "curvepoint_fp.h" 11 | #include "fp2e.h" 12 | #include "twistpoint_fp2.h" 13 | 14 | void linefunction_add_ate( 15 | fp2e_t rop11, 16 | fp2e_t rop12, 17 | fp2e_t rop13, 18 | twistpoint_fp2_t rop2, 19 | const twistpoint_fp2_t op1, 20 | const twistpoint_fp2_t op2, 21 | const curvepoint_fp_t op3, 22 | const fp2e_struct_t *r2 // r2 = y^2, see "Faster Computation of Tate Pairings" 23 | ); 24 | 25 | void linefunction_double_ate( 26 | fp2e_t rop11, 27 | fp2e_t rop12, 28 | fp2e_t rop13, 29 | twistpoint_fp2_t rop2, 30 | const twistpoint_fp2_t op1, 31 | const curvepoint_fp_t op3); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /rand/laplace.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Vuvuzela Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package rand 6 | 7 | import ( 8 | "encoding/binary" 9 | "math" 10 | ) 11 | 12 | type Laplace struct { 13 | Mu float64 14 | B float64 15 | } 16 | 17 | func (l Laplace) Uint32() uint32 { 18 | x := laplace(l.Mu, l.B) 19 | if x < 0 { 20 | return l.Uint32() 21 | } 22 | 23 | return uint32(x) 24 | } 25 | 26 | func laplace(mu, b float64) float64 { 27 | var r [8]byte 28 | if _, err := Read(r[:]); err != nil { 29 | panic(err) 30 | } 31 | 32 | x := binary.BigEndian.Uint64(r[:]) 33 | u := float64(x)/float64(^uint64(0)) - .5 34 | 35 | var abs, sign float64 36 | if u < 0 { 37 | abs = -u 38 | sign = -1 39 | } else { 40 | abs = u 41 | sign = 1 42 | } 43 | 44 | return mu - b*sign*math.Log(1-2*abs) 45 | } 46 | -------------------------------------------------------------------------------- /bn256/scalar.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: dclxvi-20130329/scalar.h 3 | * Author: Ruben Niederhagen, Peter Schwabe 4 | * Public Domain 5 | */ 6 | 7 | #ifndef SCALAR_H 8 | #define SCALAR_H 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | typedef unsigned long long scalar_t[4]; 16 | 17 | void scalar_sub_nored(scalar_t r, scalar_t x, scalar_t y); 18 | 19 | void scalar_setrandom(scalar_t rop, const scalar_t bound); 20 | 21 | void scalar_set_lluarray(scalar_t rop, unsigned long long v[4]); 22 | 23 | int scalar_getbit(const scalar_t s, unsigned int pos); 24 | 25 | // Returns the position of the most significant set bit 26 | int scalar_scanb(const scalar_t s); 27 | 28 | int scalar_iszero_vartime(const scalar_t s); 29 | 30 | void scalar_window4(signed char r[65], const scalar_t s); 31 | 32 | int scalar_lt_vartime(const scalar_t a, const scalar_t b); 33 | 34 | void scalar_print(FILE *fh, const scalar_t t); 35 | 36 | #ifdef __cplusplus 37 | } 38 | #endif 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /shuffle/shuffle_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Vuvuzela Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package shuffle 6 | 7 | import ( 8 | "testing" 9 | 10 | "vuvuzela.io/crypto/rand" 11 | ) 12 | 13 | func TestShuffle(t *testing.T) { 14 | n := 64 15 | x := make([][]byte, n) 16 | for i := 0; i < n; i++ { 17 | x[i] = []byte{byte(i)} 18 | } 19 | 20 | s := New(rand.Reader, len(x)) 21 | s.Shuffle(x) 22 | 23 | allSame := true 24 | for i := 0; i < n; i++ { 25 | if x[i][0] != byte(i) { 26 | allSame = false 27 | } 28 | } 29 | 30 | if allSame { 31 | t.Errorf("shuffler isn't shuffling") 32 | } 33 | 34 | s.Unshuffle(x) 35 | 36 | for i := 0; i < n; i++ { 37 | if x[i][0] != byte(i) { 38 | t.Errorf("unshuffle does not undo shuffle") 39 | break 40 | } 41 | } 42 | } 43 | 44 | func BenchmarkNew(b *testing.B) { 45 | for i := 0; i < b.N; i++ { 46 | New(rand.Reader, 50000) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /bn256/gfp.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Alpenhorn Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package bn256 6 | 7 | import ( 8 | "math/big" 9 | ) 10 | 11 | /* 12 | #include "fpe.h" 13 | */ 14 | import "C" 15 | 16 | type fpe C.struct_fpe_struct 17 | 18 | func (e *fpe) SetInt(x *big.Int) *fpe { 19 | c := newConvertContext() 20 | c.bytesToDoubles(new(big.Int).Mod(x, p).Bytes()) 21 | copy(e.v[:], c.doubles[:]) 22 | return e 23 | } 24 | 25 | func (e *fpe) Int() *big.Int { 26 | c := newConvertContext() 27 | out := new(big.Int) 28 | c.doublesToInt(out, &e.v[0]) 29 | return out 30 | } 31 | 32 | func (e *fpe) Marshal() []byte { 33 | out := make([]byte, numBytes) 34 | bytes := e.Int().Bytes() 35 | copy(out[numBytes-len(bytes):], bytes) 36 | return out 37 | } 38 | 39 | func (e *fpe) Unmarshal(m []byte) (*fpe, bool) { 40 | if len(m) != numBytes { 41 | return nil, false 42 | } 43 | c := newConvertContext() 44 | c.bytesToDoubles(m) 45 | copy(e.v[:], c.doubles[:]) 46 | 47 | return e, true 48 | } 49 | -------------------------------------------------------------------------------- /bn256ref/example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package bn256ref 6 | 7 | import ( 8 | "crypto/rand" 9 | ) 10 | 11 | func ExamplePair() { 12 | // This implements the tripartite Diffie-Hellman algorithm from "A One 13 | // Round Protocol for Tripartite Diffie-Hellman", A. Joux. 14 | // http://www.springerlink.com/content/cddc57yyva0hburb/fulltext.pdf 15 | 16 | // Each of three parties, a, b and c, generate a private value. 17 | a, _ := rand.Int(rand.Reader, Order) 18 | b, _ := rand.Int(rand.Reader, Order) 19 | c, _ := rand.Int(rand.Reader, Order) 20 | 21 | // Then each party calculates g₁ and g₂ times their private value. 22 | pa := new(G1).ScalarBaseMult(a) 23 | qa := new(G2).ScalarBaseMult(a) 24 | 25 | pb := new(G1).ScalarBaseMult(b) 26 | qb := new(G2).ScalarBaseMult(b) 27 | 28 | pc := new(G1).ScalarBaseMult(c) 29 | qc := new(G2).ScalarBaseMult(c) 30 | 31 | // Now each party exchanges its public values with the other two and 32 | // all parties can calculate the shared key. 33 | k1 := Pair(pb, qc) 34 | k1.ScalarMult(k1, a) 35 | 36 | k2 := Pair(pc, qa) 37 | k2.ScalarMult(k2, b) 38 | 39 | k3 := Pair(pa, qb) 40 | k3.ScalarMult(k3, c) 41 | 42 | // k1, k2 and k3 will all be equal. 43 | } 44 | -------------------------------------------------------------------------------- /onionbox/onion.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Vuvuzela Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package onionbox implements onion encryption. 6 | package onionbox // import "vuvuzela.io/crypto/onionbox" 7 | 8 | import ( 9 | "golang.org/x/crypto/nacl/box" 10 | 11 | "vuvuzela.io/crypto/rand" 12 | ) 13 | 14 | // Overhead of one layer 15 | const Overhead = 32 + box.Overhead 16 | 17 | func Seal(message []byte, nonce *[24]byte, publicKeys []*[32]byte) ([]byte, []*[32]byte) { 18 | onion := message 19 | sharedKeys := make([]*[32]byte, len(publicKeys)) 20 | for i := len(publicKeys) - 1; i >= 0; i-- { 21 | myPublicKey, myPrivateKey, err := box.GenerateKey(rand.Reader) 22 | if err != nil { 23 | panic(err) 24 | } 25 | sharedKeys[i] = new([32]byte) 26 | box.Precompute(sharedKeys[i], (*[32]byte)(publicKeys[i]), myPrivateKey) 27 | 28 | onion = box.SealAfterPrecomputation(myPublicKey[:], onion, nonce, sharedKeys[i]) 29 | } 30 | 31 | return onion, sharedKeys 32 | } 33 | 34 | func Open(onion []byte, nonce *[24]byte, sharedKeys []*[32]byte) ([]byte, bool) { 35 | var ok bool 36 | message := onion 37 | for i := 0; i < len(sharedKeys); i++ { 38 | message, ok = box.OpenAfterPrecomputation(nil, message, nonce, sharedKeys[i]) 39 | if !ok { 40 | return nil, false 41 | } 42 | } 43 | 44 | return message, true 45 | } 46 | -------------------------------------------------------------------------------- /bn256/int_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package bn256 6 | 7 | import ( 8 | "bytes" 9 | "crypto/rand" 10 | "math/big" 11 | "testing" 12 | ) 13 | 14 | func TestTripartiteDiffieHellman(t *testing.T) { 15 | a, _ := rand.Int(rand.Reader, Order) 16 | b, _ := rand.Int(rand.Reader, Order) 17 | c, _ := rand.Int(rand.Reader, Order) 18 | 19 | pa, _ := new(G1).Unmarshal(new(G1).ScalarBaseMult(a).Marshal()) 20 | qa, _ := new(G2).Unmarshal(new(G2).ScalarBaseMult(a).Marshal()) 21 | pb, _ := new(G1).Unmarshal(new(G1).ScalarBaseMult(b).Marshal()) 22 | qb, _ := new(G2).Unmarshal(new(G2).ScalarBaseMult(b).Marshal()) 23 | pc, _ := new(G1).Unmarshal(new(G1).ScalarBaseMult(c).Marshal()) 24 | qc, _ := new(G2).Unmarshal(new(G2).ScalarBaseMult(c).Marshal()) 25 | 26 | k1 := Pair(pb, qc) 27 | k1.ScalarMult(k1, a) 28 | k1Bytes := k1.Marshal() 29 | 30 | k2 := Pair(pc, qa) 31 | k2.ScalarMult(k2, b) 32 | k2Bytes := k2.Marshal() 33 | 34 | k3 := Pair(pa, qb) 35 | k3.ScalarMult(k3, c) 36 | k3Bytes := k3.Marshal() 37 | 38 | if !bytes.Equal(k1Bytes, k2Bytes) || !bytes.Equal(k2Bytes, k3Bytes) { 39 | t.Errorf("keys didn't agree") 40 | } 41 | } 42 | 43 | func BenchmarkPairing(b *testing.B) { 44 | g1 := new(G1).ScalarBaseMult(big.NewInt(44)) 45 | g2 := new(G2).ScalarBaseMult(big.NewInt(55)) 46 | for i := 0; i < b.N; i++ { 47 | Pair(g1, g2) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /bls/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 The Alpenhorn Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name Alpenhorn nor the names of its contributors may be 14 | used to endorse or promote products derived from this software without 15 | specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /ibe/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 The Alpenhorn Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name Alpenhorn nor the names of its contributors may be 14 | used to endorse or promote products derived from this software without 15 | specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /rand/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 The Vuvuzela Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name Vuvuzela nor the names of its contributors may be 14 | used to endorse or promote products derived from this software without 15 | specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /onionbox/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 The Vuvuzela Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name Vuvuzela nor the names of its contributors may be 14 | used to endorse or promote products derived from this software without 15 | specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /shuffle/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 The Vuvuzela Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name Vuvuzela nor the names of its contributors may be 14 | used to endorse or promote products derived from this software without 15 | specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /bn256/hash_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Alpenhorn Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package bn256 6 | 7 | import ( 8 | "bytes" 9 | "crypto/rand" 10 | "testing" 11 | 12 | "vuvuzela.io/crypto/bn256ref" 13 | ) 14 | 15 | func TestHashG1Ref(t *testing.T) { 16 | m := make([]byte, 64) 17 | for i := 0; i < 1000; i++ { 18 | rand.Read(m) 19 | 20 | g := new(G1).HashToPoint(m) 21 | G := new(bn256ref.G1).HashToPoint(m) 22 | 23 | gb := g.Marshal() 24 | Gb := G.Marshal() 25 | 26 | if bytes.Compare(gb, Gb) != 0 { 27 | t.Fatalf("\nmsg = %x\ngot %x\nwant %x", m, gb, Gb) 28 | } 29 | } 30 | } 31 | 32 | func TestHashG2Ref(t *testing.T) { 33 | m := make([]byte, 64) 34 | for i := 0; i < 200; i++ { 35 | rand.Read(m) 36 | 37 | g := new(G2).HashToPoint(m) 38 | G := new(bn256ref.G2).HashToPoint(m) 39 | 40 | gb := g.Marshal() 41 | Gb := G.Marshal() 42 | 43 | if bytes.Compare(gb, Gb) != 0 { 44 | t.Fatalf("\nmsg = %x\ngot %s\nwant %s", m, g, G) 45 | } 46 | } 47 | } 48 | 49 | func TestMulCofactor(t *testing.T) { 50 | for i := 0; i < 100; i++ { 51 | msg := make([]byte, 64) 52 | rand.Read(msg) 53 | 54 | pt := hashToTwistPoint(msg) 55 | 56 | g := new(twistPoint).Mul(pt, Order) 57 | if g.IsInfinity() { 58 | t.Fatal("did not expect point to be in subgroup") 59 | } 60 | 61 | pt.Mul(pt, twistCofactor) 62 | g = new(twistPoint).Mul(pt, Order) 63 | if !g.IsInfinity() { 64 | t.Fatal("expecting point to be in subgroup after multiplying by cofactor") 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /bn256ref/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 The Go Authors. All rights reserved. 2 | Portions Copyright (c) 2016 David Lazar. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above 11 | copyright notice, this list of conditions and the following disclaimer 12 | in the documentation and/or other materials provided with the 13 | distribution. 14 | * Neither the name of Google Inc. nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /bn256/twistpoint_fp2.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: dclxvi-20130329/twistpoint_fp2.h 3 | * Author: Ruben Niederhagen, Peter Schwabe 4 | * Public Domain 5 | */ 6 | 7 | #ifndef TWISTPOINT_FP2_H 8 | #define TWISTPOINT_FP2_H 9 | 10 | #include "fp2e.h" 11 | #include "scalar.h" 12 | 13 | typedef struct twistpoint_fp2_struct twistpoint_fp2_struct_t; 14 | 15 | struct twistpoint_fp2_struct { 16 | fp2e_t m_x; // X-Coordinate (Jacobian Coordinate system) 17 | fp2e_t m_y; // Y-Coordinate (Jacobian Coordinate system) 18 | fp2e_t m_z; // Z-Coordinate (Jacobian Coordinate system) 19 | fp2e_t m_t; // T = Z^2, only used during pairing computation, set to zero if not set 20 | }; 21 | 22 | typedef twistpoint_fp2_struct_t twistpoint_fp2_t[1]; 23 | 24 | void twistpoint_fp2_set(twistpoint_fp2_t rop, const twistpoint_fp2_t op); 25 | 26 | void twistpoint_fp2_setneutral(twistpoint_fp2_t rop); 27 | 28 | void twistpoint_fp2_neg(twistpoint_fp2_t rop, const twistpoint_fp2_t op); 29 | 30 | void twistpoint_fp2_set_fp2e(twistpoint_fp2_t rop, const fp2e_t x, const fp2e_t y, const fp2e_t z); 31 | 32 | void twistpoint_fp2_affineset_fp2e(twistpoint_fp2_t rop, const fp2e_t x, const fp2e_t y); 33 | 34 | void twistpoint_fp2_add_vartime(twistpoint_fp2_t rop, const twistpoint_fp2_t op1, const twistpoint_fp2_t op2); 35 | 36 | void twistpoint_fp2_double(twistpoint_fp2_t rop, const twistpoint_fp2_t op); 37 | 38 | void twistpoint_fp2_scalarmult_vartime(twistpoint_fp2_t rop, const twistpoint_fp2_t op, const scalar_t scalar); 39 | 40 | void twistpoint_fp2_print(FILE *outfile, const twistpoint_fp2_t op); 41 | 42 | // Transform to Affine Coordinates (z=1) 43 | void twistpoint_fp2_makeaffine(twistpoint_fp2_t op); 44 | 45 | #endif // ifdef TWISTPOINT_FP2_H 46 | -------------------------------------------------------------------------------- /bn256/gfp12.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Alpenhorn Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package bn256 6 | 7 | import ( 8 | "math/big" 9 | ) 10 | 11 | /* 12 | #include "fp12e.h" 13 | */ 14 | import "C" 15 | 16 | type fp12e C.struct_fp12e_struct 17 | 18 | func (e *fp12e) GetFp2e() [6]*fp2e { 19 | a := (*C.struct_fp6e_struct)(&e.m_a[0]) 20 | b := (*C.struct_fp6e_struct)(&e.m_b[0]) 21 | return [6]*fp2e{ 22 | (*fp2e)(&a.m_a[0]), 23 | (*fp2e)(&a.m_b[0]), 24 | (*fp2e)(&a.m_c[0]), 25 | (*fp2e)(&b.m_a[0]), 26 | (*fp2e)(&b.m_b[0]), 27 | (*fp2e)(&b.m_c[0]), 28 | } 29 | } 30 | 31 | func (e *fp12e) Invert(op *fp12e) *fp12e { 32 | C.fp12e_invert((*C.struct_fp12e_struct)(e), (*C.struct_fp12e_struct)(op)) 33 | return e 34 | } 35 | 36 | func (e *fp12e) Mul(op1 *fp12e, op2 *fp12e) *fp12e { 37 | C.fp12e_mul((*C.struct_fp12e_struct)(e), (*C.struct_fp12e_struct)(op1), (*C.struct_fp12e_struct)(op2)) 38 | return e 39 | } 40 | 41 | var pTwelve = new(big.Int).Exp(p, big.NewInt(12), nil) 42 | 43 | func (e *fp12e) Exp(base *fp12e, pow *big.Int) *fp12e { 44 | scalar := bigToScalar(pow, pTwelve) 45 | C.fp12e_pow_vartime((*C.struct_fp12e_struct)(e), (*C.struct_fp12e_struct)(base), scalar) 46 | return e 47 | } 48 | 49 | func (e *fp12e) Marshal() []byte { 50 | out := make([]byte, numBytes*12) 51 | xs := e.GetFp2e() 52 | for i, x := range xs { 53 | b := x.Marshal() 54 | copy(out[i*numBytes*2:], b) 55 | } 56 | return out 57 | } 58 | 59 | func (e *fp12e) Unmarshal(m []byte) (*fp12e, bool) { 60 | if len(m) != numBytes*12 { 61 | return nil, false 62 | } 63 | 64 | xs := e.GetFp2e() 65 | for i, x := range xs { 66 | _, ok := x.Unmarshal(m[i*numBytes*2 : (i+1)*numBytes*2]) 67 | if !ok { 68 | return nil, false 69 | } 70 | } 71 | return e, true 72 | } 73 | -------------------------------------------------------------------------------- /shuffle/shuffle.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Vuvuzela Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package shuffle implements cryptographic shuffling. 6 | package shuffle // import "vuvuzela.io/crypto/shuffle" 7 | 8 | import ( 9 | "bufio" 10 | "encoding/binary" 11 | "io" 12 | ) 13 | 14 | type Shuffler []int 15 | 16 | func New(rand io.Reader, n int) Shuffler { 17 | p := make(Shuffler, n) 18 | buf := make([]byte, 4) 19 | rr := bufio.NewReader(rand) 20 | for i := range p { 21 | p[i] = intn(rr, uint32(i+1), buf) 22 | } 23 | return p 24 | } 25 | 26 | func (s Shuffler) Shuffle(x [][]byte) { 27 | for i := range x { 28 | j := s[i] 29 | x[i], x[j] = x[j], x[i] 30 | } 31 | } 32 | 33 | func (s Shuffler) Unshuffle(x [][]byte) { 34 | for i := len(x) - 1; i >= 0; i-- { 35 | j := s[i] 36 | x[i], x[j] = x[j], x[i] 37 | } 38 | } 39 | 40 | func (s Shuffler) ShuffleInts(x []int) { 41 | for i := range x { 42 | j := s[i] 43 | x[i], x[j] = x[j], x[i] 44 | } 45 | } 46 | 47 | func (s Shuffler) UnshuffleInts(x []int) { 48 | for i := len(x) - 1; i >= 0; i-- { 49 | j := s[i] 50 | x[i], x[j] = x[j], x[i] 51 | } 52 | } 53 | 54 | func Shuffle[T any](rand io.Reader, x []T) Shuffler { 55 | s := New(rand, len(x)) 56 | for i := range x { 57 | j := s[i] 58 | x[i], x[j] = x[j], x[i] 59 | } 60 | return s 61 | } 62 | 63 | func Unshuffle[T any](s Shuffler, x []T) { 64 | for i := len(x) - 1; i >= 0; i-- { 65 | j := s[i] 66 | x[i], x[j] = x[j], x[i] 67 | } 68 | } 69 | 70 | func intn(rand *bufio.Reader, n uint32, buf []byte) int { 71 | max := ^uint32(0) 72 | m := max - (max % n) 73 | for { 74 | if _, err := rand.Read(buf); err != nil { 75 | panic(err) 76 | } 77 | x := binary.BigEndian.Uint32(buf) 78 | if x < m { 79 | return int(x % n) 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /bn256/consts.s: -------------------------------------------------------------------------------- 1 | # File: dclxvi-20130329/consts.s 2 | # Author: Ruben Niederhagen, Peter Schwabe 3 | # Public Domain 4 | 5 | .globl TWO_TWO 6 | .globl THREE_THREE 7 | .globl FOUR_FOUR 8 | .globl FIVE_FIVE 9 | .globl SIX_SIX 10 | .globl EIGHT_EIGHT 11 | .globl NINE_NINE 12 | .globl ONE_MINUSONE 13 | .globl MONE_MONE 14 | .globl EIGHTEEN_EIGHTEEN 15 | .globl THIRTY_THIRTY 16 | .globl ONE_SIX 17 | .globl ONE_FOUR 18 | .globl ONE_THREE 19 | .globl ONE_TWO 20 | .globl ONE_MINUSSEVEN 21 | .globl SIX_ONE 22 | .globl ZERO_ONE 23 | .globl MINUSSEVEN_ONE 24 | .globl MINUSONE_ONE 25 | .globl FOUR_MINUSSEVEN 26 | .globl THREE_MINUSONE 27 | .globl TWO_MINUSONE 28 | .globl V_V 29 | .globl V6_V6 30 | .globl VINV_VINV 31 | .globl V6INV_V6INV 32 | .globl ROUND_ROUND 33 | 34 | .p2align 4 35 | 36 | TWO_TWO: .double 2.,2. 37 | THREE_THREE: .double 3.,3. 38 | FOUR_FOUR: .double 4.,4. 39 | FIVE_FIVE: .double 5.,5. 40 | SIX_SIX: .double 6.,6. 41 | EIGHT_EIGHT: .double 8.,8. 42 | NINE_NINE: .double 9.,9. 43 | EIGHTEEN_EIGHTEEN: .double 18.,18. 44 | THIRTY_THIRTY: .double 30.,30. 45 | ONE_SIX: .double 1.,6. 46 | ONE_FOUR: .double 1.,4. 47 | ONE_THREE: .double 1.,3. 48 | ONE_TWO: .double 1.,2. 49 | ONE_MINUSSEVEN: .double 1.,-7. 50 | MINUSSEVEN_ONE: .double -7.,1. 51 | MINUSONE_ONE: .double -1.,1. 52 | SIX_ONE: .double 6.,1. 53 | ZERO_ONE: .double 0.,1. 54 | FOUR_MINUSSEVEN: .double 4.,-7. 55 | TWO_MINUSONE: .double 2.,-1. 56 | THREE_MINUSONE: .double 3.,-1. 57 | ONE_MINUSONE: .double 1.,-1. 58 | MONE_MONE: .double -1.,-1. 59 | V_V: .double 1868033.,1868033. 60 | V6_V6: .double 11208198.,11208198. 61 | VINV_VINV: .double 0.00000053532244880042272725429071400515823597743292339146137237548828125,0.00000053532244880042272725429071400515823597743292339146137237548828125 62 | V6INV_V6INV: .double 0.0000000892204081334037834640851853847121066820591295254416763782501220703125,0.0000000892204081334037834640851853847121066820591295254416763782501220703125 63 | ROUND_ROUND: .double 6755399441055744.,6755399441055744. 64 | 65 | -------------------------------------------------------------------------------- /bn256/curvepoint_fp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: dclxvi-20130329/curvepoint_fp.h 3 | * Author: Ruben Niederhagen, Peter Schwabe 4 | * Public Domain 5 | */ 6 | 7 | #ifndef CURVEPOINT_FP_H 8 | #define CURVEPOINT_FP_H 9 | 10 | #include 11 | 12 | #include "fpe.h" 13 | #include "scalar.h" 14 | 15 | /// Structure describing a point on a BN-curve 16 | typedef struct curvepoint_fp_struct curvepoint_fp_struct_t; 17 | struct curvepoint_fp_struct { 18 | fpe_t m_x; // X-Coordinate (Jacobian Coordinate system) 19 | fpe_t m_y; // Y-Coordinate (Jacobian Coordinate system) 20 | fpe_t m_z; // Y-Coordinate (Jacobian Coordinate system) 21 | fpe_t m_t; // T = Z^2, only used during pairing computation, set to zero if not set 22 | }; 23 | 24 | typedef curvepoint_fp_struct_t curvepoint_fp_t[1]; 25 | 26 | void curvepoint_fp_init(curvepoint_fp_t rop); 27 | 28 | void curvepoint_fp_init_set_str(curvepoint_fp_t rop, const char *x, const char *y, const char *z); 29 | 30 | void curvepoint_fp_init_set(curvepoint_fp_t rop, const curvepoint_fp_t op); 31 | 32 | void curvepoint_fp_init_set_fpe(curvepoint_fp_t rop, const fpe_t opx, const fpe_t opy); 33 | 34 | void curvepoint_fp_setneutral(curvepoint_fp_t rop); 35 | 36 | // Generate a point on the curve 37 | void curvepoint_fp_set_str(curvepoint_fp_t point, const char *x, const char *y, const char *z); 38 | 39 | // Generate a curvepoint_fp_t by copying the coordinates from another curvepoint_fp 40 | void curvepoint_fp_set(curvepoint_fp_t point, const curvepoint_fp_t arg); 41 | 42 | void curvepoint_fp_add_vartime(curvepoint_fp_t rop, const curvepoint_fp_t op1, const curvepoint_fp_t op2); 43 | 44 | void curvepoint_fp_double(curvepoint_fp_t rop, const curvepoint_fp_t op); 45 | 46 | void curvepoint_fp_scalarmult_vartime(curvepoint_fp_t rop, const curvepoint_fp_t op, const scalar_t s); 47 | 48 | // Compute the Inverse of a Point op, store result in rop: 49 | void curvepoint_fp_neg(curvepoint_fp_t rop, const curvepoint_fp_t op); 50 | 51 | // Transform to Affine Coordinates (z=1) 52 | void curvepoint_fp_makeaffine(curvepoint_fp_t point); 53 | 54 | // Print the (Jacobian) coordinates of a point 55 | void curvepoint_fp_print(FILE *outfile, const curvepoint_fp_t point); 56 | 57 | #endif // ifdef CURVEPOINT_FP_H 58 | -------------------------------------------------------------------------------- /bn256ref/constants.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package bn256ref 6 | 7 | import ( 8 | "math/big" 9 | ) 10 | 11 | func bigFromBase10(s string) *big.Int { 12 | n, _ := new(big.Int).SetString(s, 10) 13 | return n 14 | } 15 | 16 | // u is the BN parameter that determines the prime: 1868033³. 17 | var u = bigFromBase10("6518589491078791937") 18 | 19 | // p is a prime over which we form a basic field: 36u⁴+36u³+24u²+6u+1. 20 | var p = bigFromBase10("65000549695646603732796438742359905742825358107623003571877145026864184071783") 21 | 22 | // Order is the number of elements in both G₁ and G₂: 36u⁴+36u³+18u²+6u+1. 23 | var Order = bigFromBase10("65000549695646603732796438742359905742570406053903786389881062969044166799969") 24 | 25 | // xiToPMinus1Over6 is ξ^((p-1)/6) where ξ = i+3. 26 | var xiToPMinus1Over6 = &GFp2{bigFromBase10("8669379979083712429711189836753509758585994370025260553045152614783263110636"), bigFromBase10("19998038925833620163537568958541907098007303196759855091367510456613536016040")} 27 | 28 | // xiToPMinus1Over3 is ξ^((p-1)/3) where ξ = i+3. 29 | var xiToPMinus1Over3 = &GFp2{bigFromBase10("26098034838977895781559542626833399156321265654106457577426020397262786167059"), bigFromBase10("15931493369629630809226283458085260090334794394361662678240713231519278691715")} 30 | 31 | // xiToPMinus1Over2 is ξ^((p-1)/2) where ξ = i+3. 32 | var xiToPMinus1Over2 = &GFp2{bigFromBase10("50997318142241922852281555961173165965672272825141804376761836765206060036244"), bigFromBase10("38665955945962842195025998234511023902832543644254935982879660597356748036009")} 33 | 34 | // xiToPSquaredMinus1Over3 is ξ^((p²-1)/3) where ξ = i+3. 35 | var xiToPSquaredMinus1Over3 = bigFromBase10("65000549695646603727810655408050771481677621702948236658134783353303381437752") 36 | 37 | // xiTo2PSquaredMinus2Over3 is ξ^((2p²-2)/3) where ξ = i+3 (a cubic root of unity, mod p). 38 | var xiTo2PSquaredMinus2Over3 = bigFromBase10("4985783334309134261147736404674766913742361673560802634030") 39 | 40 | // xiToPSquaredMinus1Over6 is ξ^((1p²-1)/6) where ξ = i+3 (a cubic root of -1, mod p). 41 | var xiToPSquaredMinus1Over6 = bigFromBase10("65000549695646603727810655408050771481677621702948236658134783353303381437753") 42 | 43 | // xiTo2PMinus2Over3 is ξ^((2p-2)/3) where ξ = i+3. 44 | var xiTo2PMinus2Over3 = &GFp2{bigFromBase10("19885131339612776214803633203834694332692106372356013117629940868870585019582"), bigFromBase10("21645619881471562101905880913352894726728173167203616652430647841922248593627")} 45 | -------------------------------------------------------------------------------- /bn256/scalar.c: -------------------------------------------------------------------------------- 1 | /* 2 | * File: dclxvi-20130329/scalar.c 3 | * Author: Ruben Niederhagen, Peter Schwabe 4 | * Public Domain 5 | */ 6 | 7 | #include "scalar.h" 8 | #include 9 | #include 10 | #include 11 | 12 | void scalar_setrandom(scalar_t rop, const scalar_t bound) 13 | { 14 | int i; 15 | FILE *urand = fopen("/dev/urandom", "r"); 16 | if (urand == NULL) { 17 | fprintf(stderr, "Could not open device file /dev/urandom"); 18 | exit(1); 19 | } 20 | do { 21 | for (i = 0; i < 32; i++) 22 | i[(unsigned char *)rop] = fgetc(urand); 23 | } while (!scalar_lt_vartime(rop, bound)); 24 | fclose(urand); 25 | } 26 | 27 | void scalar_set_lluarray(scalar_t rop, unsigned long long v[4]) 28 | { 29 | int i; 30 | for (i = 0; i < 4; i++) 31 | rop[i] = v[i]; 32 | } 33 | 34 | int scalar_getbit(const scalar_t s, unsigned int pos) 35 | { 36 | assert(pos < 256); 37 | return (s[pos >> 6] >> (pos & 0x3f)) & 1; 38 | } 39 | 40 | // Returns the position of the most significant set bit 41 | int scalar_scanb(const scalar_t s) 42 | { 43 | int i; 44 | unsigned int pos = 0; 45 | for (i = 255; i > 0; i--) 46 | if (scalar_getbit(s, i) && pos == 0) 47 | pos = i; 48 | return pos; 49 | } 50 | 51 | int scalar_iszero_vartime(const scalar_t s) 52 | { 53 | return ((s[0] | s[1] | s[2] | s[3]) == 0); 54 | } 55 | 56 | void scalar_window4(signed char r[65], const scalar_t s) 57 | { 58 | char carry; 59 | int i; 60 | for (i = 0; i < 16; i++) 61 | r[i] = (s[0] >> (4 * i)) & 15; 62 | for (i = 0; i < 16; i++) 63 | r[i + 16] = (s[1] >> (4 * i)) & 15; 64 | for (i = 0; i < 16; i++) 65 | r[i + 32] = (s[2] >> (4 * i)) & 15; 66 | for (i = 0; i < 16; i++) 67 | r[i + 48] = (s[3] >> (4 * i)) & 15; 68 | 69 | /* Making it signed */ 70 | carry = 0; 71 | for (i = 0; i < 64; i++) { 72 | r[i] += carry; 73 | r[i + 1] += r[i] >> 4; 74 | r[i] &= 15; 75 | carry = r[i] >> 3; 76 | r[i] -= carry << 4; 77 | } 78 | r[64] = carry; 79 | } 80 | 81 | // Returns 1 if a < b, 0 otherwise 82 | int scalar_lt_vartime(const scalar_t a, const scalar_t b) 83 | { 84 | if (a[3] < b[3]) 85 | return 1; 86 | if (a[3] > b[3]) 87 | return 0; 88 | if (a[2] < b[2]) 89 | return 1; 90 | if (a[2] > b[2]) 91 | return 0; 92 | if (a[1] < b[1]) 93 | return 1; 94 | if (a[1] > b[1]) 95 | return 0; 96 | if (a[0] < b[0]) 97 | return 1; 98 | if (a[0] > b[0]) 99 | return 0; 100 | return 0; 101 | } 102 | 103 | void scalar_print(FILE *fh, const scalar_t t) 104 | { 105 | int i; 106 | for (i = 3; i >= 0; i--) 107 | fprintf(fh, "%llx", t[i]); 108 | } 109 | -------------------------------------------------------------------------------- /bn256/fp6e.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: dclxvi-20130329/fp6e.h 3 | * Author: Ruben Niederhagen, Peter Schwabe 4 | * Public Domain 5 | */ 6 | 7 | #ifndef FP6E_H 8 | #define FP6E_H 9 | 10 | #include "fp2e.h" 11 | 12 | // Elements from F_{p^6}= F_{p^2}[Y] / (Y^3 - xi)F_{p^2}[Y] are represented as aY^2 + bY + c 13 | typedef struct fp6e_struct fp6e_struct_t; 14 | 15 | struct fp6e_struct { 16 | fp2e_t m_a; 17 | fp2e_t m_b; 18 | fp2e_t m_c; 19 | }; 20 | 21 | typedef fp6e_struct_t fp6e_t[1]; 22 | 23 | void fp6e_short_coeffred(fp6e_t rop); 24 | 25 | // Set fp6e_t rop to given value: 26 | void fp6e_set(fp6e_t rop, const fp6e_t op); 27 | 28 | // Initialize an fp6e, set to value given in three fp2es 29 | void fp6e_set_fp2e(fp6e_t rop, const fp2e_t a, const fp2e_t b, const fp2e_t c); 30 | 31 | // Initialize an fp6e, set to value given in six strings 32 | void fp6e_set_str(fp6e_t rop, const char *a1, const char *a0, const char *b1, const char *b0, const char *c1, const char *c0); 33 | 34 | // Set rop to one: 35 | void fp6e_setone(fp6e_t rop); 36 | 37 | // Set rop to zero: 38 | void fp6e_setzero(fp6e_t rop); 39 | 40 | // Compare for equality: 41 | int fp6e_iseq(const fp6e_t op1, const fp6e_t op2); 42 | 43 | int fp6e_isone(const fp6e_t op); 44 | 45 | int fp6e_iszero(const fp6e_t op); 46 | 47 | void fp6e_cmov(fp6e_t rop, const fp6e_t op, int c); 48 | 49 | // Add two fp6e, store result in rop: 50 | void fp6e_add(fp6e_t rop, const fp6e_t op1, const fp6e_t op2); 51 | 52 | // Subtract op2 from op1, store result in rop: 53 | void fp6e_sub(fp6e_t rop, const fp6e_t op1, const fp6e_t op2); 54 | 55 | // Negate an fp6e 56 | void fp6e_neg(fp6e_t rop, const fp6e_t op); 57 | 58 | // Multiply two fp6e, store result in rop: 59 | void fp6e_mul(fp6e_t rop, const fp6e_t op1, const fp6e_t op2); 60 | 61 | // Compute the double of a square of an fp6e, store result in rop: 62 | void fp6e_squaredouble(fp6e_t rop, const fp6e_t op); 63 | 64 | // Multiply with tau: 65 | void fp6e_multau(fp6e_t rop, const fp6e_t op); 66 | 67 | void fp6e_mul_fpe(fp6e_t rop, const fp6e_t op1, const fpe_t op2); 68 | 69 | void fp6e_mul_fp2e(fp6e_t rop, const fp6e_t op1, const fp2e_t op2); 70 | 71 | // Multiply an fp6e by a short fp6e, store result in rop: 72 | // the short fp6e is given by 2 fp2e elements op2 = b2*tau + c2. 73 | void fp6e_mul_shortfp6e(fp6e_t rop, const fp6e_t op1, const fp6e_t op2); 74 | 75 | void fp6e_invert(fp6e_t rop, const fp6e_t op); 76 | 77 | void fp6e_frobenius_p(fp6e_t rop, const fp6e_t op); 78 | 79 | void fp6e_frobenius_p2(fp6e_t rop, const fp6e_t op); 80 | 81 | // Print the element to stdout: 82 | void fp6e_print(FILE *outfile, const fp6e_t op); 83 | 84 | #endif // ifndef FP6E_H 85 | -------------------------------------------------------------------------------- /rand/salsa20rand_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Vuvuzela Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package rand 6 | 7 | import ( 8 | "bufio" 9 | "crypto/rand" 10 | "crypto/sha256" 11 | "fmt" 12 | mrand "math/rand" 13 | "os" 14 | "testing" 15 | "time" 16 | ) 17 | 18 | type zeroReader struct{} 19 | 20 | func (zr *zeroReader) Read(d []byte) (n int, err error) { 21 | for i := range d { 22 | d[i] = 0 23 | } 24 | return len(d), nil 25 | } 26 | 27 | func TestRandomReads(t *testing.T) { 28 | rest := 1024 * 1024 29 | hash := sha256.New() 30 | srand := NewSalsa20Rand(new(zeroReader)) 31 | 32 | mrand.Seed(time.Now().Unix()) 33 | for rest > 0 { 34 | n := mrand.Intn(1024) 35 | if n > rest { 36 | n = rest 37 | } 38 | 39 | d := make([]byte, n) 40 | if _, err := srand.Read(d); err != nil { 41 | t.Fatalf("error: %s", err) 42 | } 43 | 44 | hash.Write(d) 45 | rest -= n 46 | } 47 | 48 | sum := hash.Sum(nil) 49 | expected := "12ccf37d07f2a467350971bbb7e83fe198f96bdd94b302ac52b100f330a466d8" 50 | actually := fmt.Sprintf("%x", sum) 51 | if actually != expected { 52 | t.Fatalf("\nexpected: %s\nactually: %s", expected, actually) 53 | } 54 | } 55 | 56 | const total = 100 * 1024 * 1024 57 | 58 | func BenchmarkCryptoRand(b *testing.B) { 59 | x := make([]byte, total) 60 | b.ResetTimer() 61 | for i := 0; i < b.N; i++ { 62 | if _, err := rand.Read(x); err != nil { 63 | panic(err) 64 | } 65 | } 66 | } 67 | 68 | func BenchmarkBufioRand(b *testing.B) { 69 | x := make([]byte, total) 70 | buf := bufio.NewReader(rand.Reader) 71 | b.ResetTimer() 72 | for i := 0; i < b.N; i++ { 73 | if _, err := buf.Read(x); err != nil { 74 | panic(err) 75 | } 76 | } 77 | } 78 | 79 | func BenchmarkDevUrandom(b *testing.B) { 80 | x := make([]byte, total) 81 | f, err := os.Open("/dev/urandom") 82 | if err != nil { 83 | panic(err) 84 | } 85 | buf := bufio.NewReader(f) 86 | b.ResetTimer() 87 | for i := 0; i < b.N; i++ { 88 | if _, err := buf.Read(x); err != nil { 89 | panic(err) 90 | } 91 | } 92 | } 93 | 94 | func BenchmarkVuvuzelaRand(b *testing.B) { 95 | x := make([]byte, total) 96 | b.ResetTimer() 97 | for i := 0; i < b.N; i++ { 98 | if _, err := Read(x); err != nil { 99 | panic(err) 100 | } 101 | } 102 | } 103 | 104 | func BenchmarkFasterRand(b *testing.B) { 105 | x := make([]byte, total) 106 | b.ResetTimer() 107 | fr := NewSalsa20Rand(Reader) 108 | for i := 0; i < b.N; i++ { 109 | if _, err := fr.Read(x); err != nil { 110 | panic(err) 111 | } 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /rand/salsa20rand.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Vuvuzela Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package rand implements a faster CSPRNG. 6 | package rand // import "vuvuzela.io/crypto/rand" 7 | 8 | import ( 9 | "crypto/rand" 10 | "encoding/binary" 11 | "io" 12 | "runtime" 13 | "sync" 14 | 15 | "golang.org/x/crypto/salsa20" 16 | ) 17 | 18 | // TODO we should occasionally reseed the PRNG 19 | 20 | type Salsa20Rand struct { 21 | zeroes []byte 22 | buffer []byte 23 | bufferOffset int 24 | 25 | key [32]byte 26 | nonce uint64 27 | } 28 | 29 | func NewSalsa20Rand(base io.Reader) *Salsa20Rand { 30 | n := 16 * 1024 31 | 32 | sr := &Salsa20Rand{ 33 | zeroes: make([]byte, n), 34 | buffer: make([]byte, n), 35 | bufferOffset: n, 36 | nonce: 0, 37 | } 38 | if n, err := base.Read(sr.key[:]); n != 32 || err != nil { 39 | panic("NewSalsa20Rand: " + err.Error()) 40 | } 41 | sr.fill() 42 | return sr 43 | } 44 | 45 | func (sr *Salsa20Rand) Read(d []byte) (n int, err error) { 46 | for len(d) > 0 { 47 | if sr.bufferOffset == len(sr.buffer) { 48 | sr.fill() 49 | } 50 | 51 | m := copy(d, sr.buffer[sr.bufferOffset:]) 52 | d = d[m:] 53 | sr.bufferOffset += m 54 | n += m 55 | } 56 | 57 | return 58 | } 59 | 60 | func (sr *Salsa20Rand) fill() { 61 | var nonce [8]byte 62 | binary.BigEndian.PutUint64(nonce[:], sr.nonce) 63 | sr.nonce += 1 64 | 65 | salsa20.XORKeyStream(sr.buffer, sr.zeroes, nonce[:], &sr.key) 66 | sr.bufferOffset = 0 67 | } 68 | 69 | type MutexReader struct { 70 | mu sync.Mutex 71 | reader io.Reader 72 | } 73 | 74 | func NewMutexReader(reader io.Reader) io.Reader { 75 | return &MutexReader{ 76 | reader: reader, 77 | } 78 | } 79 | 80 | func (mr *MutexReader) Read(d []byte) (n int, err error) { 81 | mr.mu.Lock() 82 | n, err = mr.reader.Read(d) 83 | mr.mu.Unlock() 84 | return 85 | } 86 | 87 | type PerCPUReader struct { 88 | readers []io.Reader 89 | } 90 | 91 | func NewPerCPUReader(initfunc func() io.Reader) io.Reader { 92 | readers := make([]io.Reader, runtime.NumCPU()) 93 | for i := 0; i < runtime.NumCPU(); i++ { 94 | readers[i] = initfunc() 95 | } 96 | return &PerCPUReader{ 97 | readers: readers, 98 | } 99 | } 100 | 101 | func (pcr *PerCPUReader) Read(d []byte) (n int, err error) { 102 | thiscpu := cpu() 103 | return pcr.readers[thiscpu%uint64(runtime.NumCPU())].Read(d) 104 | } 105 | 106 | var Reader = NewPerCPUReader(func() io.Reader { 107 | return NewMutexReader(NewSalsa20Rand(rand.Reader)) 108 | }) 109 | 110 | func Read(b []byte) (n int, err error) { 111 | return io.ReadFull(Reader, b) 112 | } 113 | -------------------------------------------------------------------------------- /bn256/gfp2.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Alpenhorn Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package bn256 6 | 7 | import ( 8 | "math/big" 9 | ) 10 | 11 | /* 12 | #include "fp2e.h" 13 | */ 14 | import "C" 15 | import "unsafe" 16 | 17 | type fp2e C.struct_fp2e_struct 18 | 19 | func (e *fp2e) GetXY() (*big.Int, *big.Int) { 20 | c := newConvertContext() 21 | 22 | x := new(big.Int) 23 | y := new(big.Int) 24 | doubles := (*C.double)(unsafe.Pointer(&e.v)) 25 | c.doublesFP2ToInt(x, doubles, 1) 26 | c.doublesFP2ToInt(y, doubles, 0) 27 | 28 | return x, y 29 | } 30 | 31 | func (e *fp2e) SetXY(x *big.Int, y *big.Int) *fp2e { 32 | c := newConvertContext() 33 | 34 | xBytes := new(big.Int).Mod(x, p).Bytes() 35 | yBytes := new(big.Int).Mod(y, p).Bytes() 36 | 37 | xyBytes := make([]byte, numBytes*2) 38 | copy(xyBytes[1*numBytes-len(xBytes):], xBytes) 39 | copy(xyBytes[2*numBytes-len(yBytes):], yBytes) 40 | 41 | c.bytesToDoublesFP2(xyBytes) 42 | copy(e.v[:], c.doublesFP2[:]) 43 | 44 | return e 45 | } 46 | 47 | func (e *fp2e) SetOne() *fp2e { 48 | C.fp2e_setone((*C.struct_fp2e_struct)(e)) 49 | return e 50 | } 51 | 52 | func (e *fp2e) IsZero() bool { 53 | x := C.fp2e_iszero((*C.struct_fp2e_struct)(e)) 54 | return x > 0 55 | } 56 | 57 | func (e *fp2e) Add(op1 *fp2e, op2 *fp2e) *fp2e { 58 | C.fp2e_add((*C.struct_fp2e_struct)(e), (*C.struct_fp2e_struct)(op1), (*C.struct_fp2e_struct)(op2)) 59 | return e 60 | } 61 | 62 | func (e *fp2e) Mul(op1 *fp2e, op2 *fp2e) *fp2e { 63 | C.fp2e_mul((*C.struct_fp2e_struct)(e), (*C.struct_fp2e_struct)(op1), (*C.struct_fp2e_struct)(op2)) 64 | return e 65 | } 66 | 67 | func (e *fp2e) Square(op *fp2e) *fp2e { 68 | C.fp2e_square((*C.struct_fp2e_struct)(e), (*C.struct_fp2e_struct)(op)) 69 | return e 70 | } 71 | 72 | func (e *fp2e) Exp(base *fp2e, pow *big.Int) *fp2e { 73 | scalar := bigToScalar(pow, pSquared) 74 | C.fp2e_exp((*C.struct_fp2e_struct)(e), (*C.struct_fp2e_struct)(base), scalar) 75 | return e 76 | } 77 | 78 | func (e *fp2e) Sqrt(op *fp2e) *fp2e { 79 | i := C.fp2e_sqrt((*C.struct_fp2e_struct)(e), (*C.struct_fp2e_struct)(op)) 80 | if i == 0 { 81 | return nil 82 | } else { 83 | return e 84 | } 85 | } 86 | 87 | func (e *fp2e) Marshal() []byte { 88 | out := make([]byte, numBytes*2) 89 | x, y := e.GetXY() 90 | xBytes := x.Bytes() 91 | yBytes := y.Bytes() 92 | copy(out[1*numBytes-len(xBytes):], xBytes) 93 | copy(out[2*numBytes-len(yBytes):], yBytes) 94 | return out 95 | } 96 | 97 | func (e *fp2e) Unmarshal(m []byte) (*fp2e, bool) { 98 | if len(m) != numBytes*2 { 99 | return nil, false 100 | } 101 | c := newConvertContext() 102 | c.bytesToDoublesFP2(m) 103 | copy(e.v[:], c.doublesFP2[:]) 104 | 105 | return e, true 106 | } 107 | -------------------------------------------------------------------------------- /bn256/curve.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Alpenhorn Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package bn256 6 | 7 | import ( 8 | "math/big" 9 | ) 10 | 11 | /* 12 | #include "curvepoint_fp.h" 13 | #include "parameters.h" 14 | #include "fpe.h" 15 | 16 | void curvepoint_fp_affineset_fpe(curvepoint_fp_t rop, const fpe_t x, const fpe_t y) 17 | { 18 | fpe_set(rop->m_x, x); 19 | fpe_set(rop->m_y, y); 20 | fpe_setone(rop->m_z); 21 | fpe_setzero(rop->m_t); 22 | } 23 | */ 24 | import "C" 25 | 26 | type curvePoint C.struct_curvepoint_fp_struct 27 | 28 | var curveGen = (*curvePoint)(&C.bn_curvegen[0]) 29 | 30 | func (c *curvePoint) GetXY() (*fpe, *fpe) { 31 | p := new(curvePoint).Set(c) 32 | p.MakeAffine() 33 | return (*fpe)(&p.m_x[0]), (*fpe)(&p.m_y[0]) 34 | } 35 | 36 | func (c *curvePoint) Set(a *curvePoint) *curvePoint { 37 | C.curvepoint_fp_set( 38 | (*C.struct_curvepoint_fp_struct)(c), 39 | (*C.struct_curvepoint_fp_struct)(a), 40 | ) 41 | return c 42 | } 43 | 44 | func (c *curvePoint) SetXY(x *fpe, y *fpe) *curvePoint { 45 | C.curvepoint_fp_affineset_fpe( 46 | (*C.struct_curvepoint_fp_struct)(c), 47 | (*C.struct_fpe_struct)(x), 48 | (*C.struct_fpe_struct)(y), 49 | ) 50 | return c 51 | } 52 | 53 | func (c *curvePoint) MakeAffine() *curvePoint { 54 | C.curvepoint_fp_makeaffine((*C.struct_curvepoint_fp_struct)(c)) 55 | return c 56 | } 57 | 58 | func (c *curvePoint) Neg(a *curvePoint) *curvePoint { 59 | C.curvepoint_fp_neg( 60 | (*C.struct_curvepoint_fp_struct)(c), 61 | (*C.struct_curvepoint_fp_struct)(a), 62 | ) 63 | return c 64 | } 65 | 66 | func (c *curvePoint) Add(a *curvePoint, b *curvePoint) *curvePoint { 67 | C.curvepoint_fp_add_vartime( 68 | (*C.struct_curvepoint_fp_struct)(c), 69 | (*C.struct_curvepoint_fp_struct)(a), 70 | (*C.struct_curvepoint_fp_struct)(b), 71 | ) 72 | return c 73 | } 74 | 75 | func (c *curvePoint) Mul(a *curvePoint, scalar *big.Int) *curvePoint { 76 | C.curvepoint_fp_scalarmult_vartime( 77 | (*C.struct_curvepoint_fp_struct)(c), 78 | (*C.struct_curvepoint_fp_struct)(a), 79 | bigToScalar(scalar, Order), 80 | ) 81 | return c 82 | } 83 | 84 | func (c *curvePoint) Marshal() []byte { 85 | out := make([]byte, numBytes*2) 86 | 87 | x, y := c.GetXY() 88 | copy(out, x.Marshal()) 89 | copy(out[numBytes:], y.Marshal()) 90 | 91 | return out 92 | } 93 | 94 | func (c *curvePoint) Unmarshal(m []byte) (*curvePoint, bool) { 95 | if len(m) != numBytes*2 { 96 | return nil, false 97 | } 98 | 99 | x, ok := new(fpe).Unmarshal(m[:numBytes]) 100 | if !ok { 101 | return nil, false 102 | } 103 | 104 | y, ok := new(fpe).Unmarshal(m[numBytes:]) 105 | if !ok { 106 | return nil, false 107 | } 108 | 109 | c.SetXY(x, y) 110 | 111 | return c, true 112 | } 113 | -------------------------------------------------------------------------------- /bn256/hash.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Alpenhorn Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package bn256 6 | 7 | import ( 8 | "crypto/sha256" 9 | "math/big" 10 | ) 11 | 12 | var curveB = new(big.Int).SetInt64(3) 13 | var twistB *fp2e 14 | var twistCofactor *big.Int 15 | 16 | func init() { 17 | twistB = new(fp2e).SetXY( 18 | bigFromBase10("6500054969564660373279643874235990574282535810762300357187714502686418407178"), 19 | bigFromBase10("45500384786952622612957507119651934019977750675336102500314001518804928850249"), 20 | ) 21 | 22 | twistCofactor = new(big.Int).Mul(big.NewInt(2), p) 23 | twistCofactor.Sub(twistCofactor, Order) 24 | } 25 | 26 | // Hash m into a curve point. 27 | // Based on the try-and-increment method (see hashToTwistPoint). 28 | // NOTE: This is prone to timing attacks. 29 | // TODO: pick positive or negative square root 30 | // TODO: should we hash the counter at every step? 31 | func hashToCurvePoint(m []byte) (*big.Int, *big.Int) { 32 | one := big.NewInt(1) 33 | 34 | h := sha256.Sum256(m) 35 | x := new(big.Int).SetBytes(h[:]) 36 | x.Mod(x, p) 37 | 38 | for { 39 | xxx := new(big.Int).Mul(x, x) 40 | xxx.Mul(xxx, x) 41 | t := new(big.Int).Add(xxx, curveB) 42 | 43 | y := new(big.Int).ModSqrt(t, p) 44 | if y != nil { 45 | return x, y 46 | } 47 | 48 | x.Add(x, one) 49 | } 50 | } 51 | 52 | func hashToTwistSubgroup(m []byte) *twistPoint { 53 | // pt is in E'(F_{p^2}). We must map it into the n-torsion subgroup 54 | // E'(F_{p^2})[n]. We can do this by multiplying by the cofactor: 55 | // cofactor = #E'(F_{p^2}) / n where #E'(F_{p^2}) = n(2p - n). 56 | // Order of the twist curve: https://eprint.iacr.org/2005/133.pdf 57 | pt := hashToTwistPoint(m) 58 | 59 | // TODO: there is a much faster way to multiply by the cofactor: 60 | // https://eprint.iacr.org/2008/530.pdf 61 | pt.Mul(pt, twistCofactor) 62 | pt.MakeAffine() 63 | return pt 64 | } 65 | 66 | // Hash m into a twist point. 67 | // Based on the try-and-increment method: 68 | // https://www.normalesup.org/~tibouchi/papers/bnhash-scis.pdf 69 | // https://eprint.iacr.org/2009/340.pdf 70 | // 71 | // NOTE: This is prone to timing attacks. 72 | // TODO: pick positive or negative square root 73 | // TODO: should we hash the counter at every step? 74 | func hashToTwistPoint(m []byte) *twistPoint { 75 | one := new(fp2e).SetOne() 76 | hxx := sha256.Sum256(append(m, 0)) 77 | hxy := sha256.Sum256(append(m, 1)) 78 | xx := new(big.Int).SetBytes(hxx[:]) 79 | xy := new(big.Int).SetBytes(hxy[:]) 80 | 81 | x := new(fp2e).SetXY(xx, xy) 82 | 83 | for { 84 | xxx := new(fp2e).Square(x) 85 | xxx.Mul(xxx, x) 86 | 87 | t := new(fp2e).Add(xxx, twistB) 88 | y := new(fp2e).Sqrt(t) 89 | if y != nil { 90 | pt := new(twistPoint).SetXY(x, y) 91 | pt.MakeAffine() 92 | return pt 93 | } 94 | 95 | x.Add(x, one) 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /bls/bls_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Alpenhorn Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package bls 6 | 7 | import ( 8 | "bytes" 9 | "crypto/rand" 10 | "testing" 11 | 12 | "golang.org/x/crypto/sha3" 13 | ) 14 | 15 | func TestSignVerify(t *testing.T) { 16 | for i := 0; i < 100; i++ { 17 | msg := randomMessage() 18 | pub, priv, err := GenerateKey(rand.Reader) 19 | if err != nil { 20 | t.Fatalf("error generating key: %s", err) 21 | } 22 | 23 | sig := Sign(priv, msg) 24 | ok := Verify([]*PublicKey{pub}, [][]byte{msg}, sig) 25 | if !ok { 26 | t.Fatalf("expected signature to verify: msg=%q pub=%s priv=%s sig=%#v", msg, pub.gx, priv.x, sig) 27 | } 28 | 29 | compressedSig := sig.Compress() 30 | ok = VerifyCompressed([]*PublicKey{pub}, [][]byte{msg}, compressedSig) 31 | if !ok { 32 | t.Fatalf("expected compressed signature to verify: msg=%q pub=%s priv=%s sig=%#v", msg, pub.gx, priv.x, sig) 33 | } 34 | 35 | msg[0] = ^msg[0] 36 | ok = Verify([]*PublicKey{pub}, [][]byte{msg}, sig) 37 | if ok { 38 | t.Fatalf("expected signature to not verify") 39 | } 40 | } 41 | } 42 | 43 | func TestAggregate(t *testing.T) { 44 | for i := 0; i < 100; i++ { 45 | msg1 := randomMessage() 46 | msg2 := randomMessage() 47 | msg3 := randomMessage() 48 | 49 | pub1, priv1, _ := GenerateKey(rand.Reader) 50 | pub2, priv2, _ := GenerateKey(rand.Reader) 51 | pub3, priv3, _ := GenerateKey(rand.Reader) 52 | 53 | sig1 := Sign(priv1, msg1) 54 | sig2 := Sign(priv2, msg2) 55 | sig3 := Sign(priv3, msg3) 56 | 57 | sig := Aggregate(sig1, sig2, sig3) 58 | 59 | ok := Verify([]*PublicKey{pub1, pub2, pub3}, [][]byte{msg1, msg2, msg3}, sig) 60 | if !ok { 61 | t.Fatalf("failed to verify aggregate signature") 62 | } 63 | 64 | shortSig := sig.Compress() 65 | ok = VerifyCompressed([]*PublicKey{pub1, pub2, pub3}, [][]byte{msg1, msg2, msg3}, shortSig) 66 | if !ok { 67 | t.Fatalf("failed to verify compressed aggregate signature") 68 | } 69 | 70 | sigPartial := Aggregate(sig1, sig2) 71 | ok = Verify([]*PublicKey{pub1, pub2, pub3}, [][]byte{msg1, msg2, msg3}, sigPartial) 72 | if ok { 73 | t.Fatalf("did not expect partial signature to verify") 74 | } 75 | } 76 | } 77 | 78 | func randomMessage() []byte { 79 | msg := make([]byte, 32) 80 | rand.Read(msg) 81 | return msg 82 | } 83 | 84 | func TestKnownAnswer(t *testing.T) { 85 | msg := []byte("test message") 86 | // We use sha3 instead of a zeroReader because GenerateKey 87 | // loops forever with a zeroReader. 88 | _, priv, err := GenerateKey(sha3.NewShake128()) 89 | if err != nil { 90 | t.Fatalf("error generating key: %s", err) 91 | } 92 | 93 | actual := Sign(priv, msg) 94 | expected, _ := decodeText([]byte("cAdm38gylnKd5Tq43SscV0K2ShgZ-f3-Acc-1WTV84U4QTwqCcrV47vxVl27yq2v5VGrxNJTB97V1CuQnprH1w")) 95 | if !bytes.Equal(actual, expected) { 96 | t.Fatalf("got %s, want %s", actual, expected) 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /bn256/fpe.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: dclxvi-20130329/fpe.h 3 | * Author: Ruben Niederhagen, Peter Schwabe 4 | * Public Domain 5 | */ 6 | 7 | #ifndef FPE_H 8 | #define FPE_H 9 | 10 | #include "mydouble.h" 11 | #include 12 | 13 | #ifdef BENCH 14 | unsigned long long int multpcycles; 15 | unsigned long long int nummultp; 16 | unsigned long long int nummultzerop; 17 | unsigned long long int nummultonep; 18 | unsigned long long int sqpcycles; 19 | unsigned long long int numsqp; 20 | unsigned long long invpcycles; 21 | unsigned long long numinvp; 22 | #endif 23 | 24 | typedef struct fpe_struct fpe_struct_t; 25 | 26 | struct fpe_struct { 27 | mydouble v[12]; 28 | } __attribute__((aligned(16))); 29 | 30 | typedef fpe_struct_t fpe_t[1]; 31 | 32 | void fpe_short_coeffred(fpe_t rop); 33 | 34 | // Set fpe_t rop to given value: 35 | void fpe_set(fpe_t rop, const fpe_t op); 36 | 37 | /* Communicate the fact that the fpe is reduced (and that we don't know anything more about it) */ 38 | void fpe_isreduced(fpe_t rop); 39 | 40 | // Set fpe_t rop to value given in bytearray -- inverse function to fpe_to_bytearray 41 | void fpe_set_bytearray(fpe_t rop, const unsigned char *op, size_t oplen); 42 | 43 | // Set fpe_t rop to value given in double array of length 12 44 | void fpe_set_doublearray(fpe_t rop, const mydouble op[12]); 45 | 46 | // Set rop to one 47 | void fpe_setone(fpe_t rop); 48 | 49 | // Set rop to zero 50 | void fpe_setzero(fpe_t rop); 51 | 52 | // Compare for equality: 53 | int fpe_iseq(const fpe_t op1, const fpe_t op2); 54 | 55 | // Is the element equal to 1: 56 | int fpe_isone(const fpe_t op); 57 | 58 | // Is the element equal to 0: 59 | int fpe_iszero(const fpe_t op); 60 | 61 | // Compute the negative of an fpe 62 | void fpe_neg(fpe_t rop, const fpe_t op); 63 | 64 | // Double an fpe: 65 | void fpe_double(fpe_t rop, const fpe_t op); 66 | 67 | // Triple an fpe: 68 | void fpe_triple(fpe_t rop, const fpe_t op); 69 | 70 | // Add two fpe, store result in rop: 71 | void fpe_add(fpe_t rop, const fpe_t op1, const fpe_t op2); 72 | 73 | // Subtract op2 from op1, store result in rop: 74 | void fpe_sub(fpe_t rop, const fpe_t op1, const fpe_t op2); 75 | 76 | #ifdef QHASM 77 | #define fpe_mul fpe_mul_qhasm 78 | #else 79 | #define fpe_mul fpe_mul_c 80 | #endif 81 | // Multiply two fpe, store result in rop: 82 | void fpe_mul(fpe_t rop, const fpe_t op1, const fpe_t op2); 83 | 84 | // Square an fpe, store result in rop: 85 | void fpe_square(fpe_t rop, const fpe_t op); 86 | 87 | // Compute inverse of an fpe, store result in rop: 88 | void fpe_invert(fpe_t rop, const fpe_t op1); 89 | 90 | // Print the element to stdout: 91 | void fpe_print(FILE *outfile, const fpe_t op); 92 | 93 | // Convert fpe into a bytearray 94 | void fpe_to_bytearray(unsigned char *rop, const fpe_t op); 95 | 96 | /* 97 | // Field constants 98 | fpe_t fpe_one; 99 | fpe_t zeta; // Third root of unity in F_p fulfilling Z^{p^2} = -zeta * Z 100 | fpe_t _1o3modp; // 1/3 \in \F_p 101 | // Two constants needed for the cometa-pairing computation 102 | fpe_t cometa_c0_const; 103 | fpe_t cometa_c1_const; 104 | */ 105 | 106 | #endif 107 | -------------------------------------------------------------------------------- /bn256/twist.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Alpenhorn Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package bn256 6 | 7 | import ( 8 | "math/big" 9 | ) 10 | 11 | /* 12 | #include "twistpoint_fp2.h" 13 | #include "parameters.h" 14 | */ 15 | import "C" 16 | 17 | type twistPoint C.struct_twistpoint_fp2_struct 18 | 19 | var twistGen = (*twistPoint)(&C.bn_twistgen[0]) 20 | var twistOrder *big.Int 21 | 22 | func init() { 23 | // twistOrder = n(2p-n) 24 | twistOrder = new(big.Int).Mul(p, big.NewInt(2)) 25 | twistOrder.Sub(twistOrder, Order) 26 | twistOrder.Mul(twistOrder, Order) 27 | } 28 | 29 | func (c *twistPoint) GetXY() (*fp2e, *fp2e) { 30 | p := new(twistPoint).Set(c) 31 | p.MakeAffine() 32 | return (*fp2e)(&p.m_x[0]), (*fp2e)(&p.m_y[0]) 33 | } 34 | 35 | func (c *twistPoint) Set(a *twistPoint) *twistPoint { 36 | C.twistpoint_fp2_set( 37 | (*C.struct_twistpoint_fp2_struct)(c), 38 | (*C.struct_twistpoint_fp2_struct)(a), 39 | ) 40 | return c 41 | } 42 | 43 | func (c *twistPoint) SetXY(x *fp2e, y *fp2e) *twistPoint { 44 | C.twistpoint_fp2_affineset_fp2e( 45 | (*C.struct_twistpoint_fp2_struct)(c), 46 | (*C.struct_fp2e_struct)(x), 47 | (*C.struct_fp2e_struct)(y), 48 | ) 49 | return c 50 | } 51 | 52 | func (c *twistPoint) IsInfinity() bool { 53 | z := (*fp2e)(&c.m_z[0]) 54 | return z.IsZero() 55 | } 56 | 57 | func (c *twistPoint) MakeAffine() *twistPoint { 58 | C.twistpoint_fp2_makeaffine((*C.struct_twistpoint_fp2_struct)(c)) 59 | return c 60 | } 61 | 62 | func (c *twistPoint) Neg(a *twistPoint) *twistPoint { 63 | C.twistpoint_fp2_neg( 64 | (*C.struct_twistpoint_fp2_struct)(c), 65 | (*C.struct_twistpoint_fp2_struct)(a), 66 | ) 67 | return c 68 | } 69 | 70 | func (c *twistPoint) Add(a *twistPoint, b *twistPoint) *twistPoint { 71 | C.twistpoint_fp2_add_vartime( 72 | (*C.struct_twistpoint_fp2_struct)(c), 73 | (*C.struct_twistpoint_fp2_struct)(a), 74 | (*C.struct_twistpoint_fp2_struct)(b), 75 | ) 76 | return c 77 | } 78 | 79 | // multiply within the entire curve group of size twistOrder 80 | func (c *twistPoint) Mul(a *twistPoint, scalar *big.Int) *twistPoint { 81 | C.twistpoint_fp2_scalarmult_vartime( 82 | (*C.struct_twistpoint_fp2_struct)(c), 83 | (*C.struct_twistpoint_fp2_struct)(a), 84 | bigToScalar(scalar, twistOrder), 85 | ) 86 | return c 87 | } 88 | 89 | // multiply within the n-torsion subgroup of size Order 90 | func (c *twistPoint) MulSubgroup(a *twistPoint, scalar *big.Int) *twistPoint { 91 | C.twistpoint_fp2_scalarmult_vartime( 92 | (*C.struct_twistpoint_fp2_struct)(c), 93 | (*C.struct_twistpoint_fp2_struct)(a), 94 | bigToScalar(scalar, Order), 95 | ) 96 | return c 97 | } 98 | 99 | var pSquared = new(big.Int).Mul(p, p) 100 | 101 | func (c *twistPoint) Marshal() []byte { 102 | out := make([]byte, numBytes*4) 103 | 104 | x, y := c.GetXY() 105 | copy(out, x.Marshal()) 106 | copy(out[numBytes*2:], y.Marshal()) 107 | 108 | return out 109 | } 110 | 111 | func (c *twistPoint) Unmarshal(m []byte) (*twistPoint, bool) { 112 | if len(m) != numBytes*4 { 113 | return nil, false 114 | } 115 | 116 | x, ok := new(fp2e).Unmarshal(m[:numBytes*2]) 117 | if !ok { 118 | return nil, false 119 | } 120 | 121 | y, ok := new(fp2e).Unmarshal(m[numBytes*2:]) 122 | if !ok { 123 | return nil, false 124 | } 125 | 126 | c.SetXY(x, y) 127 | 128 | return c, true 129 | } 130 | -------------------------------------------------------------------------------- /bn256/scalar_sub_nored.s: -------------------------------------------------------------------------------- 1 | # File: dclxvi-20130329/scalar_sub_nored.s 2 | # Author: Ruben Niederhagen, Peter Schwabe 3 | # Public Domain 4 | 5 | 6 | # qhasm: int64 rp 7 | 8 | # qhasm: int64 xp 9 | 10 | # qhasm: int64 yp 11 | 12 | # qhasm: input rp 13 | 14 | # qhasm: input xp 15 | 16 | # qhasm: input yp 17 | 18 | # qhasm: int64 r0 19 | 20 | # qhasm: int64 r1 21 | 22 | # qhasm: int64 r2 23 | 24 | # qhasm: int64 r3 25 | 26 | # qhasm: int64 t0 27 | 28 | # qhasm: int64 t1 29 | 30 | # qhasm: int64 t2 31 | 32 | # qhasm: int64 t3 33 | 34 | # qhasm: int64 caller1 35 | 36 | # qhasm: int64 caller2 37 | 38 | # qhasm: int64 caller3 39 | 40 | # qhasm: int64 caller4 41 | 42 | # qhasm: int64 caller5 43 | 44 | # qhasm: int64 caller6 45 | 46 | # qhasm: int64 caller7 47 | 48 | # qhasm: caller caller1 49 | 50 | # qhasm: caller caller2 51 | 52 | # qhasm: caller caller3 53 | 54 | # qhasm: caller caller4 55 | 56 | # qhasm: caller caller5 57 | 58 | # qhasm: caller caller6 59 | 60 | # qhasm: caller caller7 61 | 62 | # qhasm: stack64 caller4_stack 63 | 64 | # qhasm: stack64 caller5_stack 65 | 66 | # qhasm: stack64 caller6_stack 67 | 68 | # qhasm: stack64 caller7_stack 69 | 70 | # qhasm: enter scalar_sub_nored 71 | .text 72 | .p2align 5 73 | .globl _scalar_sub_nored 74 | .globl scalar_sub_nored 75 | _scalar_sub_nored: 76 | scalar_sub_nored: 77 | mov %rsp,%r11 78 | and $31,%r11 79 | add $0,%r11 80 | sub %r11,%rsp 81 | 82 | # qhasm: r0 = *(uint64 *)(xp + 0) 83 | # asm 1: movq 0(r0=int64#4 84 | # asm 2: movq 0(r0=%rcx 85 | movq 0(%rsi),%rcx 86 | 87 | # qhasm: r1 = *(uint64 *)(xp + 8) 88 | # asm 1: movq 8(r1=int64#5 89 | # asm 2: movq 8(r1=%r8 90 | movq 8(%rsi),%r8 91 | 92 | # qhasm: r2 = *(uint64 *)(xp + 16) 93 | # asm 1: movq 16(r2=int64#6 94 | # asm 2: movq 16(r2=%r9 95 | movq 16(%rsi),%r9 96 | 97 | # qhasm: r3 = *(uint64 *)(xp + 24) 98 | # asm 1: movq 24(r3=int64#2 99 | # asm 2: movq 24(r3=%rsi 100 | movq 24(%rsi),%rsi 101 | 102 | # qhasm: carry? r0 -= *(uint64 *)(yp + 0) 103 | # asm 1: subq 0( 8 | 9 | #include "curvepoint_fp.h" 10 | #include "final_expo.h" 11 | #include "fp12e.h" 12 | #include "fp2e.h" 13 | #include "fp6e.h" 14 | #include "linefunction.h" 15 | #include "optate.h" 16 | #include "twistpoint_fp2.h" 17 | //#include "parameters.h" 18 | 19 | extern const unsigned long bn_naflen_6uplus2; 20 | extern const scalar_t bn_6uplus2; 21 | extern const fpe_t bn_zeta2; 22 | extern const fp2e_t bn_z2p; 23 | extern const fp2e_t bn_z3p; 24 | extern const signed char bn_6uplus2_naf[66]; 25 | 26 | void optate_miller(fp12e_t rop, const twistpoint_fp2_t op1, const curvepoint_fp_t op2) 27 | { 28 | // op1 and op2 are assumed to be in affine coordinates! 29 | twistpoint_fp2_t q1, q2; //, q3; 30 | fp12e_setone(rop); 31 | 32 | fp2e_t dummy1, dummy2, dummy3; 33 | fp2e_t tfp2e1, tfp2e2; 34 | 35 | twistpoint_fp2_t r, t, mop1; 36 | twistpoint_fp2_set(r, op1); 37 | twistpoint_fp2_neg(mop1, op1); 38 | fp2e_setone(r->m_t); /* As r has to be in affine coordinates this is ok */ 39 | fp2e_setone(t->m_t); /* As t has to be in affine coordinates this is ok */ 40 | 41 | fp2e_t r2; 42 | fp2e_square(r2, op1->m_y); 43 | 44 | unsigned int i; 45 | /* 46 | for(i = bn_bitlen_6uplus2 - 1; i > 0; i--) 47 | { 48 | linefunction_double_ate(dummy1, dummy2, dummy3, r, r, op2); 49 | if(i != bn_bitlen_6uplus2 -1) fp12e_square(rop, rop); 50 | fp12e_mul_line(rop, rop, dummy1, dummy2, dummy3); 51 | 52 | if (scalar_getbit(bn_6uplus2, i - 1)) 53 | { 54 | linefunction_add_ate(dummy1, dummy2, dummy3, r, r, op1, op2, r2); 55 | fp12e_mul_line(rop, rop, dummy1, dummy2, dummy3); 56 | } 57 | } 58 | */ 59 | for (i = bn_naflen_6uplus2 - 1; i > 0; i--) { 60 | linefunction_double_ate(dummy1, dummy2, dummy3, r, r, op2); 61 | if (i != bn_naflen_6uplus2 - 1) 62 | fp12e_square(rop, rop); 63 | fp12e_mul_line(rop, rop, dummy1, dummy2, dummy3); 64 | 65 | if (bn_6uplus2_naf[i - 1] == 1) { 66 | linefunction_add_ate(dummy1, dummy2, dummy3, r, r, op1, op2, r2); 67 | fp12e_mul_line(rop, rop, dummy1, dummy2, dummy3); 68 | } 69 | if (bn_6uplus2_naf[i - 1] == -1) { 70 | linefunction_add_ate(dummy1, dummy2, dummy3, r, r, mop1, op2, r2); 71 | fp12e_mul_line(rop, rop, dummy1, dummy2, dummy3); 72 | } 73 | } 74 | 75 | /* Compute Q2 */ 76 | fp2e_mul_fpe(tfp2e1, op1->m_x, bn_zeta2); 77 | twistpoint_fp2_affineset_fp2e(q2, tfp2e1, op1->m_y); 78 | 79 | /* Compute Q1 */ 80 | fp2e_set(tfp2e1, op1->m_x); 81 | fp2e_conjugate(tfp2e1, tfp2e1); 82 | fp2e_mul(tfp2e1, tfp2e1, bn_z2p); 83 | /* 84 | printf("\n"); 85 | fp2e_print(stdout, bn_z2p); 86 | printf("\n"); 87 | */ 88 | fp2e_set(tfp2e2, op1->m_y); 89 | fp2e_conjugate(tfp2e2, tfp2e2); 90 | fp2e_mul(tfp2e2, tfp2e2, bn_z3p); 91 | twistpoint_fp2_affineset_fp2e(q1, tfp2e1, tfp2e2); 92 | 93 | /* Compute Q3 */ 94 | //fp2e_mul_fpe(tfp2e3, tfp2e1, bn_zeta2); 95 | //fp2e_neg(tfp2e2, tfp2e2); 96 | //twistpoint_fp2_affineset_fp2e(q3, tfp2e3, tfp2e2); 97 | 98 | /* Remaining line functions */ 99 | fp2e_square(r2, q1->m_y); 100 | linefunction_add_ate(dummy1, dummy2, dummy3, t, r, q1, op2, r2); 101 | fp12e_mul_line(rop, rop, dummy1, dummy2, dummy3); 102 | 103 | fp2e_square(r2, q2->m_y); 104 | linefunction_add_ate(dummy1, dummy2, dummy3, t, t, q2, op2, r2); 105 | fp12e_mul_line(rop, rop, dummy1, dummy2, dummy3); 106 | 107 | //fp2e_square(r2, q3->m_y); 108 | //linefunction_add_ate(dummy1, dummy2, dummy3, t, t, q3, op2, r2); 109 | //fp12e_mul_line(rop, rop, dummy1, dummy2, dummy3); 110 | } 111 | 112 | void optate(fp12e_t rop, const twistpoint_fp2_t op1, const curvepoint_fp_t op2) 113 | { 114 | int retone; 115 | fp12e_t d; 116 | fp12e_setone(d); 117 | optate_miller(rop, op1, op2); 118 | final_expo(rop); 119 | retone = fp2e_iszero(op1->m_z); 120 | retone |= fpe_iszero(op2->m_z); 121 | fp12e_cmov(rop, d, retone); 122 | } 123 | -------------------------------------------------------------------------------- /bn256/final_expo.c: -------------------------------------------------------------------------------- 1 | /* 2 | * File: dclxvi-20130329/final_expo.c 3 | * Author: Ruben Niederhagen, Peter Schwabe 4 | * Public Domain 5 | */ 6 | 7 | #include "final_expo.h" 8 | #include "fpe.h" 9 | #include 10 | 11 | extern const scalar_t bn_u; 12 | extern const scalar_t bn_v_scalar; 13 | extern const unsigned long bn_u_bitsize; 14 | 15 | static void fp12e_powv_special_square(fp12e_t rop, const fp12e_t op) 16 | { 17 | fp12e_t tmp0, tmp1, tmp2; 18 | //XXX Implement 19 | fp12e_special_square_finexp(tmp0, op); 20 | fp12e_special_square_finexp(tmp0, tmp0); 21 | fp12e_special_square_finexp(tmp0, tmp0); // t0 = op^8 22 | fp12e_special_square_finexp(tmp1, tmp0); 23 | fp12e_special_square_finexp(tmp1, tmp1); 24 | fp12e_special_square_finexp(tmp1, tmp1); // t1 = op^64 25 | fp12e_conjugate(tmp2, tmp0); // t2 = op^-8 26 | fp12e_mul(tmp2, tmp2, op); // t2 = op^-7 27 | fp12e_mul(tmp2, tmp2, tmp1); // tmp2 = op^57 28 | fp12e_special_square_finexp(tmp2, tmp2); 29 | fp12e_special_square_finexp(tmp2, tmp2); 30 | fp12e_special_square_finexp(tmp2, tmp2); 31 | fp12e_special_square_finexp(tmp2, tmp2); 32 | fp12e_special_square_finexp(tmp2, tmp2); 33 | fp12e_special_square_finexp(tmp2, tmp2); 34 | fp12e_special_square_finexp(tmp2, tmp2); // tmp2 = op^(2^7*57) = op^7296 35 | fp12e_mul(tmp2, tmp2, op); // tmp2 = op^7297 36 | fp12e_special_square_finexp(tmp2, tmp2); 37 | fp12e_special_square_finexp(tmp2, tmp2); 38 | fp12e_special_square_finexp(tmp2, tmp2); 39 | fp12e_special_square_finexp(tmp2, tmp2); 40 | fp12e_special_square_finexp(tmp2, tmp2); 41 | fp12e_special_square_finexp(tmp2, tmp2); 42 | fp12e_special_square_finexp(tmp2, tmp2); 43 | fp12e_special_square_finexp(tmp2, tmp2); // tmp2 = op^(7297*256) = op^1868032 44 | fp12e_mul(rop, tmp2, op); // rop = op^v 45 | } 46 | 47 | static void fp12e_powu_special_square(fp12e_t rop, const fp12e_t op) 48 | { 49 | fp12e_powv_special_square(rop, op); 50 | fp12e_powv_special_square(rop, rop); 51 | fp12e_powv_special_square(rop, rop); 52 | } 53 | 54 | void final_expo(fp12e_t rop) 55 | { 56 | /* This all has to change to support scalar_t instead of mpz_t */ 57 | // First part: (p^6 - 1) 58 | fp12e_t dummy1, dummy2, fp, fp2, fp3, fu, fu2, fu3, fu2p, fu3p, y0, y1, y2, y3, y4, y5, y6, t0, t1; 59 | fp12e_set(dummy1, rop); 60 | 61 | // This is exactly the p^6-Frobenius action: 62 | fp6e_neg(rop->m_a, rop->m_a); 63 | 64 | fp12e_invert(dummy2, dummy1); 65 | fp12e_mul(rop, rop, dummy2); 66 | // After this point, rop has norm 1, so we can use 67 | // special squaring and exponentiation. 68 | 69 | // Second part: (p^2 + 1) 70 | fp12e_set(dummy1, rop); 71 | fp12e_frobenius_p2(rop, rop); 72 | fp12e_mul(rop, rop, dummy1); 73 | 74 | /* Hard part */ 75 | fp12e_frobenius_p(fp, rop); 76 | fp12e_frobenius_p2(fp2, rop); 77 | fp12e_frobenius_p(fp3, fp2); 78 | 79 | fp12e_powu_special_square(fu, rop); 80 | fp12e_powu_special_square(fu2, fu); 81 | fp12e_powu_special_square(fu3, fu2); 82 | fp12e_frobenius_p(y3, fu); 83 | fp12e_frobenius_p(fu2p, fu2); 84 | fp12e_frobenius_p(fu3p, fu3); 85 | fp12e_frobenius_p2(y2, fu2); 86 | fp12e_mul(y0, fp, fp2); 87 | fp12e_mul(y0, y0, fp3); 88 | 89 | fp12e_conjugate(y1, rop); 90 | 91 | fp12e_conjugate(y5, fu2); 92 | fp12e_conjugate(y3, y3); 93 | fp12e_mul(y4, fu, fu2p); 94 | fp12e_conjugate(y4, y4); 95 | 96 | fp12e_mul(y6, fu3, fu3p); 97 | fp12e_conjugate(y6, y6); 98 | 99 | //t0 := fp12square(y6); 100 | fp12e_special_square_finexp(t0, y6); 101 | //t0 := t0*y4; 102 | fp12e_mul(t0, t0, y4); 103 | //t0 := t0*y5; 104 | fp12e_mul(t0, t0, y5); 105 | //t1 := y3*y5; 106 | fp12e_mul(t1, y3, y5); 107 | //t1 := t1*t0; 108 | fp12e_mul(t1, t1, t0); 109 | //t0 := t0*y2; 110 | fp12e_mul(t0, t0, y2); 111 | //t1 := t1^2; 112 | fp12e_special_square_finexp(t1, t1); 113 | //t1 := t1*t0; 114 | fp12e_mul(t1, t1, t0); 115 | //t1 := t1^2; 116 | fp12e_special_square_finexp(t1, t1); 117 | //t0 := t1*y1; 118 | fp12e_mul(t0, t1, y1); 119 | //t1 := t1*y0; 120 | fp12e_mul(t1, t1, y0); 121 | //t0 := t0^2; 122 | fp12e_special_square_finexp(t0, t0); 123 | //t0 := t0*t1; 124 | fp12e_mul(rop, t0, t1); 125 | } 126 | -------------------------------------------------------------------------------- /bn256ref/hash.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 David Lazar. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package bn256ref 6 | 7 | import ( 8 | "crypto/sha256" 9 | "math/big" 10 | ) 11 | 12 | var ( 13 | bigZero = big.NewInt(0) 14 | bigOne = big.NewInt(1) 15 | bigTwo = big.NewInt(2) 16 | bigThree = big.NewInt(3) 17 | bigFour = big.NewInt(4) 18 | ) 19 | 20 | // Hash m into a curve point. 21 | // Based on the try-and-increment method (see hashToTwistPoint). 22 | // NOTE: This is prone to timing attacks. 23 | // TODO: pick positive or negative square root 24 | // TODO: should we hash the counter at every step? 25 | func hashToCurvePoint(m []byte) *curvePoint { 26 | h := sha256.Sum256(m) 27 | x := new(big.Int).SetBytes(h[:]) 28 | x.Mod(x, p) 29 | 30 | for { 31 | xxx := new(big.Int).Mul(x, x) 32 | xxx.Mul(xxx, x) 33 | t := new(big.Int).Add(xxx, curveB) 34 | 35 | y := new(big.Int).ModSqrt(t, p) 36 | if y != nil { 37 | return &curvePoint{x, y, big.NewInt(1), big.NewInt(1)} 38 | } 39 | 40 | x.Add(x, big.NewInt(1)) 41 | } 42 | } 43 | 44 | // Hash m into a twist point. 45 | // Based on the try-and-increment method: 46 | // https://www.normalesup.org/~tibouchi/papers/bnhash-scis.pdf 47 | // https://eprint.iacr.org/2009/340.pdf 48 | // 49 | // NOTE: This is prone to timing attacks. 50 | // TODO: pick positive or negative square root 51 | // TODO: should we hash the counter at every step? 52 | func hashToTwistPoint(m []byte) *twistPoint { 53 | pool := new(bnPool) 54 | one := newGFp2(pool).SetOne() 55 | 56 | hx := sha256.Sum256(append(m, 0)) 57 | hy := sha256.Sum256(append(m, 1)) 58 | 59 | x := &GFp2{ 60 | new(big.Int).SetBytes(hx[:]), 61 | new(big.Int).SetBytes(hy[:]), 62 | } 63 | x.Minimal() 64 | 65 | for { 66 | xxx := newGFp2(pool).Square(x, pool) 67 | xxx.Mul(xxx, x, pool) 68 | 69 | t := newGFp2(pool).Add(xxx, twistB) 70 | //t.Minimal() 71 | y := newGFp2(pool).Sqrt(t) 72 | if y != nil { 73 | pt := &twistPoint{ 74 | x, 75 | y, 76 | &GFp2{big.NewInt(0), big.NewInt(1)}, 77 | &GFp2{big.NewInt(0), big.NewInt(1)}, 78 | } 79 | 80 | return pt 81 | } 82 | 83 | x.Add(x, one) 84 | } 85 | } 86 | 87 | func hashToTwistSubgroup(m []byte) *twistPoint { 88 | pool := new(bnPool) 89 | 90 | pt := hashToTwistPoint(m) 91 | 92 | // pt is in E'(F_{p^2}). We must map it into the n-torsion subgroup 93 | // E'(F_{p^2})[n]. We can do this by multiplying by the cofactor: 94 | // cofactor = #E'(F_{p^2}) / n where #E'(F_{p^2}) = n(2p - n). 95 | // Order of the twist curve: https://eprint.iacr.org/2005/133.pdf 96 | cofactor := new(big.Int).Mul(bigTwo, p) 97 | cofactor.Sub(cofactor, Order) 98 | 99 | // TODO: there is a much faster way to multiply by the cofactor: 100 | // https://eprint.iacr.org/2008/530.pdf 101 | ptc := newTwistPoint(pool).Mul(pt, cofactor, pool) 102 | ptc.MakeAffine(pool) 103 | 104 | return ptc 105 | } 106 | 107 | var gfp2NegativeOne = &GFp2{bigZero, big.NewInt(-1)} 108 | 109 | func init() { 110 | gfp2NegativeOne.Minimal() 111 | } 112 | 113 | // Sqrt computes the square root of a in the GFp2 field (F_{p^2}). 114 | // This is Algorithm 9 from https://eprint.iacr.org/2012/685.pdf 115 | // Assumes p is a prime with p = 3 mod 4, and that a is Minimal. 116 | func (e *GFp2) Sqrt(a *GFp2) *GFp2 { 117 | pool := new(bnPool) 118 | 119 | q := pool.Get().Sub(p, bigThree) 120 | q.Div(q, bigFour) 121 | a1 := newGFp2(pool).Exp(a, q, pool) 122 | alpha := newGFp2(pool).Mul(a1, a, pool) 123 | alpha.Mul(a1, alpha, pool) 124 | a0 := newGFp2(pool).Conjugate(alpha) 125 | a0.Mul(a0, alpha, pool) 126 | if a0.x.Cmp(gfp2NegativeOne.x) == 0 && a0.y.Cmp(gfp2NegativeOne.y) == 0 { 127 | return nil 128 | } 129 | 130 | x0 := newGFp2(pool).Mul(a1, a, pool) 131 | if alpha.x.Cmp(gfp2NegativeOne.x) == 0 && alpha.y.Cmp(gfp2NegativeOne.y) == 0 { 132 | i := &GFp2{bigOne, bigZero} 133 | e.Mul(i, x0, pool) 134 | return e 135 | } else { 136 | q.Sub(p, bigOne) 137 | q.Div(q, bigTwo) 138 | b := newGFp2(pool).Add(newGFp2(pool).SetOne(), alpha) 139 | b.Exp(b, q, pool) 140 | e.Mul(b, x0, pool) 141 | return e 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /bn256ref/gfp12.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package bn256ref 6 | 7 | // For details of the algorithms used, see "Multiplication and Squaring on 8 | // Pairing-Friendly Fields, Devegili et al. 9 | // http://eprint.iacr.org/2006/471.pdf. 10 | 11 | import ( 12 | "math/big" 13 | ) 14 | 15 | // gfP12 implements the field of size p¹² as a quadratic extension of gfP6 16 | // where ω²=τ. 17 | type gfP12 struct { 18 | x, y *gfP6 // value is xω + y 19 | } 20 | 21 | func newGFp12(pool *bnPool) *gfP12 { 22 | return &gfP12{newGFp6(pool), newGFp6(pool)} 23 | } 24 | 25 | func (e *gfP12) String() string { 26 | return "(" + e.x.String() + "," + e.y.String() + ")" 27 | } 28 | 29 | func (e *gfP12) Put(pool *bnPool) { 30 | e.x.Put(pool) 31 | e.y.Put(pool) 32 | } 33 | 34 | func (e *gfP12) Set(a *gfP12) *gfP12 { 35 | e.x.Set(a.x) 36 | e.y.Set(a.y) 37 | return e 38 | } 39 | 40 | func (e *gfP12) SetZero() *gfP12 { 41 | e.x.SetZero() 42 | e.y.SetZero() 43 | return e 44 | } 45 | 46 | func (e *gfP12) SetOne() *gfP12 { 47 | e.x.SetZero() 48 | e.y.SetOne() 49 | return e 50 | } 51 | 52 | func (e *gfP12) Minimal() { 53 | e.x.Minimal() 54 | e.y.Minimal() 55 | } 56 | 57 | func (e *gfP12) IsZero() bool { 58 | e.Minimal() 59 | return e.x.IsZero() && e.y.IsZero() 60 | } 61 | 62 | func (e *gfP12) IsOne() bool { 63 | e.Minimal() 64 | return e.x.IsZero() && e.y.IsOne() 65 | } 66 | 67 | func (e *gfP12) Conjugate(a *gfP12) *gfP12 { 68 | e.x.Negative(a.x) 69 | e.y.Set(a.y) 70 | return a 71 | } 72 | 73 | func (e *gfP12) Negative(a *gfP12) *gfP12 { 74 | e.x.Negative(a.x) 75 | e.y.Negative(a.y) 76 | return e 77 | } 78 | 79 | // Frobenius computes (xω+y)^p = x^p ω·ξ^((p-1)/6) + y^p 80 | func (e *gfP12) Frobenius(a *gfP12, pool *bnPool) *gfP12 { 81 | e.x.Frobenius(a.x, pool) 82 | e.y.Frobenius(a.y, pool) 83 | e.x.MulScalar(e.x, xiToPMinus1Over6, pool) 84 | return e 85 | } 86 | 87 | // FrobeniusP2 computes (xω+y)^p² = x^p² ω·ξ^((p²-1)/6) + y^p² 88 | func (e *gfP12) FrobeniusP2(a *gfP12, pool *bnPool) *gfP12 { 89 | e.x.FrobeniusP2(a.x) 90 | e.x.MulGFP(e.x, xiToPSquaredMinus1Over6) 91 | e.y.FrobeniusP2(a.y) 92 | return e 93 | } 94 | 95 | func (e *gfP12) Add(a, b *gfP12) *gfP12 { 96 | e.x.Add(a.x, b.x) 97 | e.y.Add(a.y, b.y) 98 | return e 99 | } 100 | 101 | func (e *gfP12) Sub(a, b *gfP12) *gfP12 { 102 | e.x.Sub(a.x, b.x) 103 | e.y.Sub(a.y, b.y) 104 | return e 105 | } 106 | 107 | func (e *gfP12) Mul(a, b *gfP12, pool *bnPool) *gfP12 { 108 | tx := newGFp6(pool) 109 | tx.Mul(a.x, b.y, pool) 110 | t := newGFp6(pool) 111 | t.Mul(b.x, a.y, pool) 112 | tx.Add(tx, t) 113 | 114 | ty := newGFp6(pool) 115 | ty.Mul(a.y, b.y, pool) 116 | t.Mul(a.x, b.x, pool) 117 | t.MulTau(t, pool) 118 | e.y.Add(ty, t) 119 | e.x.Set(tx) 120 | 121 | tx.Put(pool) 122 | ty.Put(pool) 123 | t.Put(pool) 124 | return e 125 | } 126 | 127 | func (e *gfP12) MulScalar(a *gfP12, b *gfP6, pool *bnPool) *gfP12 { 128 | e.x.Mul(e.x, b, pool) 129 | e.y.Mul(e.y, b, pool) 130 | return e 131 | } 132 | 133 | func (c *gfP12) Exp(a *gfP12, power *big.Int, pool *bnPool) *gfP12 { 134 | sum := newGFp12(pool) 135 | sum.SetOne() 136 | t := newGFp12(pool) 137 | 138 | for i := power.BitLen() - 1; i >= 0; i-- { 139 | t.Square(sum, pool) 140 | if power.Bit(i) != 0 { 141 | sum.Mul(t, a, pool) 142 | } else { 143 | sum.Set(t) 144 | } 145 | } 146 | 147 | c.Set(sum) 148 | 149 | sum.Put(pool) 150 | t.Put(pool) 151 | 152 | return c 153 | } 154 | 155 | func (e *gfP12) Square(a *gfP12, pool *bnPool) *gfP12 { 156 | // Complex squaring algorithm 157 | v0 := newGFp6(pool) 158 | v0.Mul(a.x, a.y, pool) 159 | 160 | t := newGFp6(pool) 161 | t.MulTau(a.x, pool) 162 | t.Add(a.y, t) 163 | ty := newGFp6(pool) 164 | ty.Add(a.x, a.y) 165 | ty.Mul(ty, t, pool) 166 | ty.Sub(ty, v0) 167 | t.MulTau(v0, pool) 168 | ty.Sub(ty, t) 169 | 170 | e.y.Set(ty) 171 | e.x.Double(v0) 172 | 173 | v0.Put(pool) 174 | t.Put(pool) 175 | ty.Put(pool) 176 | 177 | return e 178 | } 179 | 180 | func (e *gfP12) Invert(a *gfP12, pool *bnPool) *gfP12 { 181 | // See "Implementing cryptographic pairings", M. Scott, section 3.2. 182 | // ftp://136.206.11.249/pub/crypto/pairings.pdf 183 | t1 := newGFp6(pool) 184 | t2 := newGFp6(pool) 185 | 186 | t1.Square(a.x, pool) 187 | t2.Square(a.y, pool) 188 | t1.MulTau(t1, pool) 189 | t1.Sub(t2, t1) 190 | t2.Invert(t1, pool) 191 | 192 | e.x.Negative(a.x) 193 | e.y.Set(a.y) 194 | e.MulScalar(e, t2, pool) 195 | 196 | t1.Put(pool) 197 | t2.Put(pool) 198 | 199 | return e 200 | } 201 | -------------------------------------------------------------------------------- /bn256/parameters.c: -------------------------------------------------------------------------------- 1 | /* 2 | * File: dclxvi-20130329/parameters.c 3 | * Author: Ruben Niederhagen, Peter Schwabe 4 | * Public Domain 5 | */ 6 | 7 | #include "curvepoint_fp.h" 8 | #include "fp12e.h" 9 | #include "fp2e.h" 10 | #include "fp6e.h" 11 | #include "fpe.h" 12 | #include "scalar.h" 13 | #include "twistpoint_fp2.h" 14 | 15 | #ifdef __cplusplus 16 | #define EXTERN extern 17 | #else 18 | #define EXTERN 19 | #endif 20 | 21 | //EXTERN const scalar_t bn_6uplus2 = {0x1EC817A18A131208ULL,2,0,0}; 22 | #define BN_6UPLUS2_NAFLEN 66 23 | EXTERN const unsigned long bn_naflen_6uplus2 = BN_6UPLUS2_NAFLEN; 24 | EXTERN const signed char bn_6uplus2_naf[BN_6UPLUS2_NAFLEN] = {0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, -1, 0, 1, 0, 0, 0, 1, 0, -1, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 1}; 25 | //EXTERN const scalar_t bn_u = {0x5BBC1015F02AC17DULL, 0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000000000000000ULL}; 26 | EXTERN const scalar_t bn_n = {0x1A2EF45B57AC7261ULL, 0x2E8D8E12F82B3924ULL, 0xAA6FECB86184DC21ULL, 0x8FB501E34AA387F9ULL}; 27 | EXTERN const scalar_t bn_pminus2 = {0x185CAC6C5E089665ULL, 0xEE5B88D120B5B59EULL, 0xAA6FECB86184DC21ULL, 0x8FB501E34AA387F9ULL}; 28 | 29 | //EXTERN const unsigned long bn_u_bitsize = 63; 30 | 31 | EXTERN const double bn_v = 1868033.; 32 | EXTERN const double bn_v6 = 11208198.; 33 | const char *bn_pstr = "65000549695646603732796438742359905742825358107623003571877145026864184071783"; 34 | EXTERN const scalar_t bn_v_scalar = {1868033, 0, 0, 0}; 35 | 36 | EXTERN const fpe_t bn_zeta = {{{-5604098, -934016, -934016, 2, 0, 0, -5604096, -934016, -934016, 1, 0, 0}}}; /* zeta */ 37 | EXTERN const fpe_t bn_zeta2 = {{{5604097, 934016, 934016, -2, 0, 0, -5604102, -934016, -934016, 0, 0, 0}}}; /* zeta^2 */ 38 | 39 | EXTERN const curvepoint_fp_t bn_curvegen = {{{{{1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.}}}, 40 | {{{-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}}, 41 | {{{1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.}}}, 42 | {{{0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.}}}}}; 43 | 44 | EXTERN const twistpoint_fp2_t bn_twistgen = {{{{{490313, 4260028, -821156, -818020, 106592, -171108, 757738, 545601, 597403, 45 | 366066, -270886, -169528, 3101279, 2043941, -726481, 382478, -650880, -891316, 46 | -13923, 327200, -110487, 473555, -7301, 608340}}}, 47 | {{{-4628877, 3279202, 431044, 459682, -606446, -924615, -927454, 90760, 13692, 48 | -225706, -430013, -373196, 3004032, 4097571, 380900, 919715, -640623, -402833, 49 | -729700, -163786, -332478, -440873, 510935, 593941}}}, 50 | {{{1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.}}}, 51 | {{{0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.}}}}}; 52 | 53 | EXTERN const fp2e_t bn_z2p = {{{-3981901, -4468327, 248857, -740622, 900229, -562222, 54 | 260246, -632491, -928317, -38527, 838674, 36774, -2702081, 3668149, 55 | -873042, 304894, 876721, 213663, 56 | 562599, -128685, -325465, 518143, 457851, 750024}}}; /* Z^(2p) */ 57 | EXTERN const fp2e_t bn_z3p = {{{-1220868, -3662603, -18020, -54060, 771971, 447880, 58 | -925219, -907622, 808438, 557280, -170086, -510257, -548011, -1644029, 59 | 332930, -869243, -918612, 60 | -887802, -656367, -101068, 599384, -69882, -756823, -402435}}}; /* Z^(3p) */ 61 | 62 | EXTERN const fp2e_t bn_ypminus1 = {{{-3981901, -4468327, 248857, -740622, 900229, 63 | -562222, 260246, -632491, -928317, -38527, 838674, 36774, -2702081, 64 | 3668149, -873042, 304894, 876721, 65 | 213663, 562599, -128685, -325465, 518143, 457851, 750024}}}; // Y^{p-1} lies in F_{p^2} 66 | EXTERN const fp2e_t bn_zpminus1 = {{{-127312, 512442, -137362, 859841, -693124, 477483, 67 | -456715, 571378, -391523, 771884, -684646, 729153, 4294836, 3621570, 68 | -839768, -538090, -213833, 69 | -814642, -240945, -172644, 308331, -116810, 574718, 249147}}}; // Z^{p-1}, lies in F_{p^2} 70 | 71 | EXTERN const fp2e_t bn_ypminus1_squ = {{{1555911, 5331252, -776828, 226463, 72 | 691213, -261413, -410662, -394138, -432410, -178831, -475754, 73 | 92316, -5497403, -1697028, 207147, -413437, 74 | -291878, 77064, 214666, 415072, -853656, 644193, 622068, 571473}}}; // (Y^{p-1})^2 i F_{p^2} 75 | 76 | #undef EXTERN 77 | -------------------------------------------------------------------------------- /bn256/parameters.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: dclxvi-20130329/parameters.h 3 | * Author: Ruben Niederhagen, Peter Schwabe 4 | * Public Domain 5 | */ 6 | 7 | #ifndef PARAMETERS_H 8 | #define PARAMETERS_H 9 | 10 | #include "curvepoint_fp.h" 11 | #include "twistpoint_fp2.h" 12 | 13 | extern const curvepoint_fp_t bn_curvegen; 14 | extern const twistpoint_fp2_t bn_twistgen; 15 | 16 | /* TODO: The parameters now all have to change to the new layout using doubles 17 | 18 | // Parameters used in fp.c 19 | 20 | // Parameters used in fp2.c 21 | 22 | // Parameters used in fp6.c 23 | #define BN_XI "1", "1" 24 | #define BN_YPMINUS1 "58218003500903600357625264234292989477935184013976377803379043379990513611334", "26288856584553239150834106295213109733170772302989655986730925339013803127666" 25 | #define BN_ZETA "5958342662886596505216018177552825854576057147370867553330" 26 | #define BN_XI2 "2", "82434016654300679721217353503190038836571781811386228921167322412819029493182" 27 | #define BN_1O27XI3 "33584229007307684330866329205003349155640355552786982153068168390407752756482", "79380904926363617509320414484553370731513567670223775998161125286418324697139" 28 | #define BN_1O3XI3 "54956011102867119814144902335460025891047854540924152614111548275212686328789", "54956011102867119814144902335460025891047854540924152614111548275212686328787" 29 | #define BN_1O3XI "54956011102867119814144902335460025891047854540924152614111548275212686328789", "54956011102867119814144902335460025891047854540924152614111548275212686328789" 30 | #define BN_1O3MODP "54956011102867119814144902335460025891047854540924152614111548275212686328789" 31 | #define BN_COMETA_C0_CONST "82434016654300679717245125061265641166427769693017678351449950981238451124296" 32 | #define BN_COMETA_C1_CONST "82434016654300679719231239282227840001499775752201953636308636697028740308739" 33 | 34 | // Parameters used in fp12.c 35 | #define BN_TAU "0", "0", "0", "1", "0", "0" // constant tau used to construct F_p^12 as F_p^6[Z]/ (Z^2 - tau) 36 | #define BN_ZPMINUS1 "56591613210034336671768069300567745343090470721508699612907758494087266915999", "8151674858040474603082263872746642797519072844079438446757658431600919538185" // Z^(p-1) 37 | #define BN_ZPMINUS1INV "16664399093237715933911902173291824865135557508817972186165572841237392240398", "80230987376282538953239279322325535591602771678144871210569992544851954063250" // Z^(1-p) 38 | 39 | // Parameters used in curve.c 40 | #define BN_X "6917529027641089837" // parameter x used to generate the curve (see "Pairing-Friendly Elliptic Curves of Prime Order") 41 | #define BN_N "82434016654300679721217353503190038836284668564296686430114510052556401373769" // prime order of E(F_p) 42 | #define BN_TRACE "287113247089542491052812360262628119415" // trace of Frobenius of the curve 43 | 44 | 45 | #define BN_CHI "1194458535516712696617215684417624257030666067240995530739989845741099828184808045812676871691350143622814961863857773132424482094537445009010868364905329475952468280063652444489821109532139390264709695335860793910425342433575735069323405841687561063024994400628664553215353435760722989078898251407419402247808499909280746379875725289212217012702226622857832645189461706430174895107087213658428058993109042366769257992607327945724517833626182446630118382398741490471673207917676536121877458679494141432659879148773761631097881935530150704252360233040678259785011038361825754014829846445352865867168990611182985694796026875346359128391415471663605963714512918697891431453354985338626546912529078714232526052412652263727800637424674871891769013049427162670429595810069240578680572440695968919901414853005710542714187307687895455094601680687073002240" // exponent of final exponentiation 46 | #define BN_CHICOMP "560169404838696232357056645449876352982160355741045729238356103537505929443608386408569742458511103733336876593838432319207912979028941305055706044190307030642152225405672930668086933610791936427274683600439499924717813785715163257" // exponent of final exponentiation for compressed pairing 47 | #define BN_LOOPLENGTH_ETA "11916685325773193009570696613837024235910666865622157670373" 48 | #define BN_B "24" // parameter b in the curve equation x^2 = y^3 + b 49 | 50 | 51 | 52 | 53 | 54 | // Parameters used in points.c 55 | #define BN_CURVEGEN "17813601848253033635698781672015468536630294081954948396510129954996309182771", "32952084653957203951573828884064840686196769247059424207939710944223386035556", "1" 56 | #define BN_TWISTGEN_X "621974397985525318194063125170198577902540556498747469157675653746576620880", "6251805185683980258298929625871846172079392273578387836099945035602364239135" 57 | #define BN_TWISTGEN_Y "49990908316789968724860573235913273901071484323829192314337721068681689250452", "19258290530482130955008764894053126575339703184772660063788583927864324464626" 58 | 59 | // Parameters used for OptAte computation in ate_optate.c 60 | #define BN_ZETA2 "82434016654300679715259010840303442331355763633833403066591265265448161939852" // zeta^2 61 | #define BN_Z2P "58218003500903600357625264234292989477935184013976377803379043379990513611334", "26288856584553239150834106295213109733170772302989655986730925339013803127666" // Z^(2p) 62 | #define BN_Z3P "36850984595653579060793000368378943551009490063938417941824057646362957363077", "73701969191307158121586000736757887102018980127876835883648115292725914726154" // Z^(3p) 63 | 64 | */ 65 | #endif 66 | -------------------------------------------------------------------------------- /ibe/ibe.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Alpenhorn Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package ibe implements Identity-Based Encryption (IBE). 6 | // 7 | // This package implements Hybrid-IBE from 8 | // "Identity Based Encryption Without Redundancy" 9 | // http://cseweb.ucsd.edu/~mihir/cse208-06/libert-quisquater-ibe-acns-05.pdf. 10 | // This schemes transforms the BF-IBE scheme (BasicIndent) into an 11 | // IND-ID-CCA2 secure scheme. 12 | package ibe // import "vuvuzela.io/crypto/ibe" 13 | 14 | import ( 15 | "crypto/rand" 16 | "encoding/json" 17 | "fmt" 18 | "io" 19 | "math/big" 20 | 21 | "golang.org/x/crypto/nacl/secretbox" 22 | "golang.org/x/crypto/sha3" 23 | 24 | "vuvuzela.io/crypto/bn256" 25 | ) 26 | 27 | const sizeOfG1 = 64 28 | const Overhead = sizeOfG1 + secretbox.Overhead 29 | 30 | type MasterPublicKey struct { 31 | g1 *bn256.G1 32 | } 33 | 34 | type MasterPrivateKey struct { 35 | s *big.Int 36 | } 37 | 38 | type IdentityPrivateKey struct { 39 | d *bn256.G2 40 | q *bn256.G2 41 | } 42 | 43 | func Setup(random io.Reader) (*MasterPublicKey, *MasterPrivateKey) { 44 | secret, err := rand.Int(random, bn256.Order) 45 | if err != nil { 46 | panic(err) 47 | } 48 | public := new(bn256.G1).ScalarBaseMult(secret) 49 | return &MasterPublicKey{public}, &MasterPrivateKey{secret} 50 | } 51 | 52 | func Extract(priv *MasterPrivateKey, id []byte) *IdentityPrivateKey { 53 | q := new(bn256.G2).HashToPoint(id) 54 | d := new(bn256.G2).ScalarMult(q, priv.s) 55 | return &IdentityPrivateKey{d: d, q: q} 56 | } 57 | 58 | type Ciphertext struct { 59 | U *bn256.G1 60 | V []byte 61 | } 62 | 63 | func (c Ciphertext) String() string { 64 | return fmt.Sprintf("ibe.Ciphertext(%s, %x)", c.U, c.V) 65 | } 66 | 67 | func (c Ciphertext) MarshalBinary() ([]byte, error) { 68 | return append(c.U.Marshal(), c.V...), nil 69 | } 70 | 71 | func (c *Ciphertext) UnmarshalBinary(data []byte) error { 72 | var ok bool 73 | c.U, ok = new(bn256.G1).Unmarshal(data[0:64]) 74 | if !ok { 75 | return fmt.Errorf("failed to unmarshal ciphertext") 76 | } 77 | c.V = data[64:] 78 | return nil 79 | } 80 | 81 | func Encrypt(random io.Reader, pub *MasterPublicKey, id []byte, msg []byte) Ciphertext { 82 | q := new(bn256.G2).HashToPoint(id) 83 | g := bn256.Pair(pub.g1, q) 84 | 85 | r, err := rand.Int(random, bn256.Order) 86 | if err != nil { 87 | panic(err) 88 | } 89 | 90 | rp := new(bn256.G1).ScalarBaseMult(r) 91 | er := new(bn256.GT).ScalarMult(g, r) 92 | 93 | shake := sha3.NewShake256() 94 | shake.Write(q.Marshal()) 95 | shake.Write(rp.Marshal()) 96 | shake.Write(er.Marshal()) 97 | 98 | var sk [32]byte 99 | shake.Read(sk[:]) 100 | 101 | box := secretbox.Seal(nil, msg, new([24]byte), &sk) 102 | 103 | return Ciphertext{ 104 | U: rp, 105 | V: box, 106 | } 107 | } 108 | 109 | func Decrypt(priv *IdentityPrivateKey, c Ciphertext) ([]byte, bool) { 110 | e := bn256.Pair(c.U, priv.d) 111 | 112 | shake := sha3.NewShake256() 113 | shake.Write(priv.q.Marshal()) 114 | shake.Write(c.U.Marshal()) 115 | shake.Write(e.Marshal()) 116 | 117 | var sk [32]byte 118 | shake.Read(sk[:]) 119 | 120 | return secretbox.Open(nil, c.V, new([24]byte), &sk) 121 | } 122 | 123 | func (pk *MasterPublicKey) Aggregate(keys ...*MasterPublicKey) *MasterPublicKey { 124 | pk.g1 = new(bn256.G1) 125 | for _, key := range keys { 126 | pk.g1.Add(pk.g1, key.g1) 127 | } 128 | return pk 129 | } 130 | 131 | func (sk *IdentityPrivateKey) Aggregate(keys ...*IdentityPrivateKey) *IdentityPrivateKey { 132 | sk.d = new(bn256.G2) 133 | for _, key := range keys { 134 | sk.d.Add(sk.d, key.d) 135 | } 136 | sk.q = new(bn256.G2).Set(keys[0].q) // TODO check all the same 137 | return sk 138 | } 139 | 140 | func (pk *MasterPublicKey) MarshalBinary() ([]byte, error) { 141 | return pk.g1.Marshal(), nil 142 | } 143 | 144 | func (pk *MasterPublicKey) UnmarshalBinary(data []byte) error { 145 | pk.g1 = new(bn256.G1) 146 | _, ok := pk.g1.Unmarshal(data) 147 | if !ok { 148 | return fmt.Errorf("failed to decode ibe.MasterPublicKey") 149 | } 150 | return nil 151 | } 152 | 153 | func (pk *MasterPublicKey) MarshalJSON() ([]byte, error) { 154 | return json.Marshal(pk.g1.Marshal()) 155 | } 156 | 157 | func (pk *MasterPublicKey) UnmarshalJSON(data []byte) error { 158 | var b []byte 159 | if err := json.Unmarshal(data, &b); err != nil { 160 | return err 161 | } 162 | pk.g1 = new(bn256.G1) 163 | _, ok := pk.g1.Unmarshal(b) 164 | if !ok { 165 | return fmt.Errorf("failed to decode ibe.MasterPublicKey") 166 | } 167 | return nil 168 | } 169 | 170 | func (sk *IdentityPrivateKey) MarshalBinary() ([]byte, error) { 171 | d := sk.d.Marshal() 172 | q := sk.q.Marshal() 173 | return append(d, q...), nil 174 | } 175 | 176 | func (sk *IdentityPrivateKey) UnmarshalBinary(data []byte) error { 177 | if len(data) != 256 { 178 | return fmt.Errorf("short data: %d", len(data)) 179 | } 180 | sk.d = new(bn256.G2) 181 | _, ok := sk.d.Unmarshal(data[:128]) 182 | if !ok { 183 | return fmt.Errorf("failed to decode ibe.IdentityPrivateKey") 184 | } 185 | sk.q = new(bn256.G2) 186 | _, ok = sk.q.Unmarshal(data[128:]) 187 | if !ok { 188 | return fmt.Errorf("failed to decode ibe.IdentityPrivateKey") 189 | } 190 | return nil 191 | } 192 | -------------------------------------------------------------------------------- /bn256ref/gfp2.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package bn256ref 6 | 7 | // For details of the algorithms used, see "Multiplication and Squaring on 8 | // Pairing-Friendly Fields, Devegili et al. 9 | // http://eprint.iacr.org/2006/471.pdf. 10 | 11 | import ( 12 | "math/big" 13 | ) 14 | 15 | // GFp2 implements a field of size p² as a quadratic extension of the base 16 | // field where i²=-1. 17 | type GFp2 struct { 18 | x, y *big.Int // value is xi+y. 19 | } 20 | 21 | func NewGFp2() *GFp2 { 22 | return &GFp2{new(big.Int), new(big.Int)} 23 | } 24 | 25 | func newGFp2(pool *bnPool) *GFp2 { 26 | return &GFp2{pool.Get(), pool.Get()} 27 | } 28 | 29 | func (e *GFp2) String() string { 30 | x := new(big.Int).Mod(e.x, p) 31 | y := new(big.Int).Mod(e.y, p) 32 | return "(" + x.String() + "," + y.String() + ")" 33 | } 34 | 35 | func (e *GFp2) GetXY() (*big.Int, *big.Int) { 36 | return e.x, e.y 37 | } 38 | 39 | // TODO awkward: bnPool is not public 40 | func (e *GFp2) Put(pool *bnPool) { 41 | pool.Put(e.x) 42 | pool.Put(e.y) 43 | } 44 | 45 | func (e *GFp2) Set(a *GFp2) *GFp2 { 46 | e.x.Set(a.x) 47 | e.y.Set(a.y) 48 | return e 49 | } 50 | 51 | func (e *GFp2) SetXY(x, y *big.Int) *GFp2 { 52 | e.x.Set(x) 53 | e.y.Set(y) 54 | return e 55 | } 56 | 57 | func (e *GFp2) SetZero() *GFp2 { 58 | e.x.SetInt64(0) 59 | e.y.SetInt64(0) 60 | return e 61 | } 62 | 63 | func (e *GFp2) SetOne() *GFp2 { 64 | e.x.SetInt64(0) 65 | e.y.SetInt64(1) 66 | return e 67 | } 68 | 69 | func (e *GFp2) Minimal() { 70 | if e.x.Sign() < 0 || e.x.Cmp(p) >= 0 { 71 | e.x.Mod(e.x, p) 72 | } 73 | if e.y.Sign() < 0 || e.y.Cmp(p) >= 0 { 74 | e.y.Mod(e.y, p) 75 | } 76 | } 77 | 78 | func (e *GFp2) IsZero() bool { 79 | return e.x.Sign() == 0 && e.y.Sign() == 0 80 | } 81 | 82 | func (e *GFp2) IsOne() bool { 83 | if e.x.Sign() != 0 { 84 | return false 85 | } 86 | words := e.y.Bits() 87 | return len(words) == 1 && words[0] == 1 88 | } 89 | 90 | func (e *GFp2) Eq(g *GFp2) bool { 91 | e.Minimal() 92 | g.Minimal() 93 | return e.x.Cmp(g.x) == 0 && e.y.Cmp(g.y) == 0 94 | } 95 | 96 | func (e *GFp2) Conjugate(a *GFp2) *GFp2 { 97 | e.y.Set(a.y) 98 | e.x.Neg(a.x) 99 | return e 100 | } 101 | 102 | func (e *GFp2) Negative(a *GFp2) *GFp2 { 103 | e.x.Neg(a.x) 104 | e.y.Neg(a.y) 105 | return e 106 | } 107 | 108 | func (e *GFp2) Add(a, b *GFp2) *GFp2 { 109 | e.x.Add(a.x, b.x) 110 | e.y.Add(a.y, b.y) 111 | return e 112 | } 113 | 114 | func (e *GFp2) Sub(a, b *GFp2) *GFp2 { 115 | e.x.Sub(a.x, b.x) 116 | e.y.Sub(a.y, b.y) 117 | return e 118 | } 119 | 120 | func (e *GFp2) Double(a *GFp2) *GFp2 { 121 | e.x.Lsh(a.x, 1) 122 | e.y.Lsh(a.y, 1) 123 | return e 124 | } 125 | 126 | func (c *GFp2) Exp(a *GFp2, power *big.Int, pool *bnPool) *GFp2 { 127 | sum := newGFp2(pool) 128 | sum.SetOne() 129 | t := newGFp2(pool) 130 | 131 | for i := power.BitLen() - 1; i >= 0; i-- { 132 | t.Square(sum, pool) 133 | if power.Bit(i) != 0 { 134 | sum.Mul(t, a, pool) 135 | } else { 136 | sum.Set(t) 137 | } 138 | } 139 | 140 | c.Set(sum) 141 | 142 | sum.Put(pool) 143 | t.Put(pool) 144 | 145 | return c 146 | } 147 | 148 | // See "Multiplication and Squaring in Pairing-Friendly Fields", 149 | // http://eprint.iacr.org/2006/471.pdf 150 | func (e *GFp2) Mul(a, b *GFp2, pool *bnPool) *GFp2 { 151 | tx := pool.Get().Mul(a.x, b.y) 152 | t := pool.Get().Mul(b.x, a.y) 153 | tx.Add(tx, t) 154 | tx.Mod(tx, p) 155 | 156 | ty := pool.Get().Mul(a.y, b.y) 157 | t.Mul(a.x, b.x) 158 | ty.Sub(ty, t) 159 | e.y.Mod(ty, p) 160 | e.x.Set(tx) 161 | 162 | pool.Put(tx) 163 | pool.Put(ty) 164 | pool.Put(t) 165 | 166 | return e 167 | } 168 | 169 | func (e *GFp2) MulScalar(a *GFp2, b *big.Int) *GFp2 { 170 | e.x.Mul(a.x, b) 171 | e.y.Mul(a.y, b) 172 | return e 173 | } 174 | 175 | // MulXi sets e=ξa where ξ=i+3 and then returns e. 176 | func (e *GFp2) MulXi(a *GFp2, pool *bnPool) *GFp2 { 177 | // (xi+y)(i+3) = (3x+y)i+(3y-x) 178 | tx := pool.Get().Lsh(a.x, 1) 179 | tx.Add(tx, a.x) 180 | tx.Add(tx, a.y) 181 | 182 | ty := pool.Get().Lsh(a.y, 1) 183 | ty.Add(ty, a.y) 184 | ty.Sub(ty, a.x) 185 | 186 | e.x.Set(tx) 187 | e.y.Set(ty) 188 | 189 | pool.Put(tx) 190 | pool.Put(ty) 191 | 192 | return e 193 | } 194 | 195 | func (e *GFp2) Square(a *GFp2, pool *bnPool) *GFp2 { 196 | // Complex squaring algorithm: 197 | // (xi+b)² = (x+y)(y-x) + 2*i*x*y 198 | t1 := pool.Get().Sub(a.y, a.x) 199 | t2 := pool.Get().Add(a.x, a.y) 200 | ty := pool.Get().Mul(t1, t2) 201 | ty.Mod(ty, p) 202 | 203 | t1.Mul(a.x, a.y) 204 | t1.Lsh(t1, 1) 205 | 206 | e.x.Mod(t1, p) 207 | e.y.Set(ty) 208 | 209 | pool.Put(t1) 210 | pool.Put(t2) 211 | pool.Put(ty) 212 | 213 | return e 214 | } 215 | 216 | func (e *GFp2) Invert(a *GFp2, pool *bnPool) *GFp2 { 217 | // See "Implementing cryptographic pairings", M. Scott, section 3.2. 218 | // ftp://136.206.11.249/pub/crypto/pairings.pdf 219 | t := pool.Get() 220 | t.Mul(a.y, a.y) 221 | t2 := pool.Get() 222 | t2.Mul(a.x, a.x) 223 | t.Add(t, t2) 224 | 225 | inv := pool.Get() 226 | inv.ModInverse(t, p) 227 | 228 | e.x.Neg(a.x) 229 | e.x.Mul(e.x, inv) 230 | e.x.Mod(e.x, p) 231 | 232 | e.y.Mul(a.y, inv) 233 | e.y.Mod(e.y, p) 234 | 235 | pool.Put(t) 236 | pool.Put(t2) 237 | pool.Put(inv) 238 | 239 | return e 240 | } 241 | -------------------------------------------------------------------------------- /bls/bls.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Alpenhorn Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package bls implements BLS aggregate signatures. 6 | // 7 | // This package implements the scheme described in 8 | // "Aggregate and Verifiably Encrypted Signatures from Bilinear Maps" 9 | // by Boneh, Gentry, Lynn, and Shacham (Eurocrypt 2003): 10 | // https://www.iacr.org/archive/eurocrypt2003/26560416/26560416.pdf. 11 | package bls // import "vuvuzela.io/crypto/bls" 12 | 13 | import ( 14 | "crypto/sha256" 15 | "crypto/subtle" 16 | "encoding/base64" 17 | "errors" 18 | "io" 19 | "math/big" 20 | 21 | "vuvuzela.io/crypto/bn256" 22 | ) 23 | 24 | const CompressedSize = 32 25 | 26 | type PrivateKey struct { 27 | x *big.Int 28 | } 29 | 30 | type PublicKey struct { 31 | gx *bn256.G2 32 | } 33 | 34 | type Signature []byte 35 | 36 | var g2gen = new(bn256.G2).ScalarBaseMult(big.NewInt(1)) 37 | 38 | func GenerateKey(rand io.Reader) (*PublicKey, *PrivateKey, error) { 39 | x, gx, err := bn256.RandomG2(rand) 40 | if err != nil { 41 | return nil, nil, err 42 | } 43 | 44 | return &PublicKey{gx}, &PrivateKey{x}, nil 45 | } 46 | 47 | func Sign(privateKey *PrivateKey, message []byte) Signature { 48 | h := new(bn256.G1).HashToPoint(message) 49 | hx := new(bn256.G1).ScalarMult(h, privateKey.x) 50 | return Signature(hx.Marshal()) 51 | } 52 | 53 | // Aggregate combines signatures on distinct messages. The messages must 54 | // be distinct, otherwise the scheme is vulnerable to chosen-key attack. 55 | func Aggregate(sigs ...Signature) Signature { 56 | var sum *bn256.G1 57 | for i, sig := range sigs { 58 | hx, ok := new(bn256.G1).Unmarshal(sig) 59 | if !ok { 60 | panic("invalid signature") 61 | } 62 | if i == 0 { 63 | sum = new(bn256.G1).Set(hx) 64 | } else { 65 | sum.Add(sum, hx) 66 | } 67 | } 68 | return Signature(sum.Marshal()) 69 | } 70 | 71 | // Compress reduces the size of a signature by dropping its y-coordinate. 72 | func (sig Signature) Compress() *[CompressedSize]byte { 73 | // only keep the x-coordinate 74 | var compressed [CompressedSize]byte 75 | copy(compressed[:], sig[0:32]) 76 | return &compressed 77 | } 78 | 79 | // Verify verifies an aggregate signature. Returns false if messages 80 | // are not distinct or if sig is not a valid signature. 81 | func Verify(keys []*PublicKey, messages [][]byte, sig Signature) bool { 82 | hx, ok := new(bn256.G1).Unmarshal(sig) 83 | if !ok { 84 | return false 85 | } 86 | 87 | if !distinct(messages) { 88 | return false 89 | } 90 | 91 | var sum *bn256.GT 92 | for i := range messages { 93 | h := new(bn256.G1).HashToPoint(messages[i]) 94 | p := bn256.Pair(h, keys[i].gx) 95 | if i == 0 { 96 | sum = p 97 | } else { 98 | sum.Add(sum, p) 99 | } 100 | } 101 | 102 | u := bn256.Pair(hx, g2gen) 103 | return subtle.ConstantTimeCompare(u.Marshal(), sum.Marshal()) == 1 104 | } 105 | 106 | // VerifyCompressed verifies a compressed aggregate signature. Returns 107 | // false if messages are not distinct. 108 | func VerifyCompressed(keys []*PublicKey, messages [][]byte, sig *[CompressedSize]byte) bool { 109 | if !distinct(messages) { 110 | return false 111 | } 112 | 113 | xCord := new(big.Int).SetBytes(sig[:]) 114 | hx, ok := new(bn256.G1).FromX(xCord) 115 | if !ok { 116 | return false 117 | } 118 | 119 | var sum *bn256.GT 120 | for i := range messages { 121 | h := new(bn256.G1).HashToPoint(messages[i]) 122 | p := bn256.Pair(h, keys[i].gx) 123 | if i == 0 { 124 | sum = p 125 | } else { 126 | sum.Add(sum, p) 127 | } 128 | } 129 | 130 | u := bn256.Pair(hx, g2gen) 131 | ub := u.Marshal() 132 | vb := sum.Marshal() 133 | ok1 := subtle.ConstantTimeCompare(ub, vb) == 1 134 | 135 | uinv := new(bn256.GT).Neg(u) 136 | uinvb := uinv.Marshal() 137 | ok2 := subtle.ConstantTimeCompare(uinvb, vb) == 1 138 | 139 | return ok1 || ok2 140 | } 141 | 142 | func distinct(msgs [][]byte) bool { 143 | m := make(map[[32]byte]bool) 144 | for _, msg := range msgs { 145 | h := sha256.Sum256(msg) 146 | if m[h] { 147 | return false 148 | } 149 | m[h] = true 150 | } 151 | return true 152 | } 153 | 154 | func (pk *PublicKey) MarshalText() ([]byte, error) { 155 | return encodeToText(pk.gx.Marshal()), nil 156 | } 157 | 158 | func (pk *PublicKey) UnmarshalText(data []byte) error { 159 | bs, err := decodeText(data) 160 | if err != nil { 161 | return err 162 | } 163 | pk.gx = new(bn256.G2) 164 | _, ok := pk.gx.Unmarshal(bs) 165 | if !ok { 166 | return errors.New("bls.PublicKey: failed to unmarshal underlying point") 167 | } 168 | return nil 169 | } 170 | 171 | func (pk *PublicKey) MarshalBinary() ([]byte, error) { 172 | return pk.gx.Marshal(), nil 173 | } 174 | 175 | func (pk *PublicKey) UnmarshalBinary(data []byte) error { 176 | pk.gx = new(bn256.G2) 177 | _, ok := pk.gx.Unmarshal(data) 178 | if !ok { 179 | return errors.New("bls.PublicKey: failed to unmarshal underlying point") 180 | } 181 | return nil 182 | } 183 | 184 | func encodeToText(data []byte) []byte { 185 | buf := make([]byte, base64.RawURLEncoding.EncodedLen(len(data))) 186 | base64.RawURLEncoding.Encode(buf, data) 187 | return buf 188 | } 189 | 190 | func decodeText(data []byte) ([]byte, error) { 191 | buf := make([]byte, base64.RawURLEncoding.DecodedLen(len(data))) 192 | n, err := base64.RawURLEncoding.Decode(buf, data) 193 | return buf[:n], err 194 | } 195 | -------------------------------------------------------------------------------- /bn256/mul.c: -------------------------------------------------------------------------------- 1 | /* 2 | * File: dclxvi-20130329/mul.c 3 | * Author: Ruben Niederhagen, Peter Schwabe 4 | * Public Domain 5 | */ 6 | 7 | #include "mul.h" 8 | #include "mydouble.h" 9 | #include 10 | 11 | extern const double bn_v; 12 | extern const double bn_v6; 13 | 14 | void polymul(mydouble *h, const mydouble *f, const mydouble *g) 15 | { 16 | mydouble t[24]; 17 | t[0] = f[0] * g[0]; 18 | t[1] = f[0] * g[1] + f[1] * g[0]; 19 | t[2] = 6 * f[1] * g[1] + (f[0] * g[2] + f[2] * g[0]); 20 | t[3] = (f[1] * g[2] + f[2] * g[1]) * 6 + (f[0] * g[3] + f[3] * g[0]); 21 | t[4] = (f[1] * g[3] + f[2] * g[2] + f[3] * g[1]) * 6 + (f[0] * g[4] + f[4] * g[0]); 22 | t[5] = (f[1] * g[4] + f[2] * g[3] + f[3] * g[2] + f[4] * g[1]) * 6 + (f[0] * g[5] + f[5] * g[0]); 23 | t[6] = (f[1] * g[5] + f[2] * g[4] + f[3] * g[3] + f[4] * g[2] + f[5] * g[1]) * 6 + f[0] * g[6] + f[6] * g[0]; 24 | t[7] = (f[0] * g[7] + f[1] * g[6] + f[2] * g[5] + f[3] * g[4] + f[4] * g[3] + f[5] * g[2] + f[6] * g[1] + f[7] * g[0]); 25 | t[8] = (f[1] * g[7] + f[7] * g[1]) * 6 + (f[0] * g[8] + f[2] * g[6] + f[3] * g[5] + f[4] * g[4] + f[5] * g[3] + f[6] * g[2] + f[8] * g[0]); 26 | t[9] = (f[1] * g[8] + f[2] * g[7] + f[7] * g[2] + f[8] * g[1]) * 6 + (f[0] * g[9] + f[3] * g[6] + f[4] * g[5] + f[5] * g[4] + f[6] * g[3] + f[9] * g[0]); 27 | t[10] = (f[1] * g[9] + f[2] * g[8] + f[3] * g[7] + f[7] * g[3] + f[8] * g[2] + f[9] * g[1]) * 6 + (f[0] * g[10] + f[4] * g[6] + f[5] * g[5] + f[6] * g[4] + f[10] * g[0]); 28 | t[11] = (f[1] * g[10] + f[2] * g[9] + f[3] * g[8] + f[4] * g[7] + f[7] * g[4] + f[8] * g[3] + f[9] * g[2] + f[10] * g[1]) * 6 + (f[0] * g[11] + f[5] * g[6] + f[6] * g[5] + f[11] * g[0]); 29 | t[12] = (f[1] * g[11] + f[2] * g[10] + f[3] * g[9] + f[4] * g[8] + f[5] * g[7] + f[7] * g[5] + f[8] * g[4] + f[9] * g[3] + f[10] * g[2] + f[11] * g[1]) * 6 + f[6] * g[6]; 30 | t[13] = (f[2] * g[11] + f[3] * g[10] + f[4] * g[9] + f[5] * g[8] + f[6] * g[7] + f[7] * g[6] + f[8] * g[5] + f[9] * g[4] + f[10] * g[3] + f[11] * g[2]); 31 | t[14] = f[7] * g[7] * 6 + (f[3] * g[11] + f[4] * g[10] + f[5] * g[9] + f[6] * g[8] + f[8] * g[6] + f[9] * g[5] + f[10] * g[4] + f[11] * g[3]); 32 | t[15] = (f[7] * g[8] + f[8] * g[7]) * 6 + (f[4] * g[11] + f[5] * g[10] + f[6] * g[9] + f[9] * g[6] + f[10] * g[5] + f[11] * g[4]); 33 | t[16] = (f[7] * g[9] + f[8] * g[8] + f[9] * g[7]) * 6 + (f[5] * g[11] + f[6] * g[10] + f[10] * g[6] + f[11] * g[5]); 34 | t[17] = (f[7] * g[10] + f[8] * g[9] + f[9] * g[8] + f[10] * g[7]) * 6 + (f[6] * g[11] + f[11] * g[6]); 35 | t[18] = (f[7] * g[11] + f[8] * g[10] + f[9] * g[9] + f[10] * g[8] + f[11] * g[7]) * 6; 36 | t[19] = (f[8] * g[11] + f[9] * g[10] + f[10] * g[9] + f[11] * g[8]); 37 | t[20] = (f[9] * g[11] + f[10] * g[10] + f[11] * g[9]); 38 | t[21] = (f[10] * g[11] + f[11] * g[10]); 39 | t[22] = f[11] * g[11]; 40 | int i; 41 | for (i = 0; i < 23; i++) 42 | h[i] = t[i]; 43 | } 44 | 45 | void degred(mydouble *h) 46 | { 47 | h[0] = h[0] - h[12] + 6 * h[15] - 2 * h[18] - 6 * h[21]; 48 | h[1] = h[1] - h[13] + h[16] - 2 * h[19] - h[22]; 49 | h[2] = h[2] - h[14] + h[17] - 2 * h[20]; 50 | h[3] = h[3] - h[12] + 5 * h[15] - h[18] - 8 * h[21]; 51 | h[4] = h[4] - 6 * h[13] + 5 * h[16] - 6 * h[19] - 8 * h[22]; 52 | h[5] = h[5] - 6 * h[14] + 5 * h[17] - 6 * h[20]; 53 | h[6] = h[6] - 4 * h[12] + 18 * h[15] - 3 * h[18]; 54 | h[6] -= 30 * h[21]; 55 | h[7] = h[7] - 4 * h[13] + 3 * h[16] - 3 * h[19] - 5 * h[22]; 56 | h[8] = h[8] - 4 * h[14] + 3 * h[17] - 3 * h[20]; 57 | h[9] = h[9] - h[12] + 2 * h[15] + h[18] - 9 * h[21]; 58 | h[10] = h[10] - 6 * h[13] + 2 * h[16] + 6 * h[19] - 9 * h[22]; 59 | h[11] = h[11] - 6 * h[14] + 2 * h[17] + 6 * h[20]; 60 | } 61 | 62 | void coeffred_round_par(mydouble *h) 63 | { 64 | mydouble carry = 0; 65 | 66 | carry = round(h[1] / bn_v); 67 | h[1] = remround(h[1], bn_v); 68 | h[2] += carry; 69 | carry = round(h[4] / bn_v); 70 | h[4] = remround(h[4], bn_v); 71 | h[5] += carry; 72 | carry = round(h[7] / bn_v); 73 | h[7] = remround(h[7], bn_v); 74 | h[8] += carry; 75 | carry = round(h[10] / bn_v); 76 | h[10] = remround(h[10], bn_v); 77 | h[11] += carry; 78 | 79 | carry = round(h[2] / bn_v); 80 | h[2] = remround(h[2], bn_v); 81 | h[3] += carry; 82 | carry = round(h[5] / bn_v); 83 | h[5] = remround(h[5], bn_v); 84 | h[6] += carry; 85 | carry = round(h[8] / bn_v); 86 | h[8] = remround(h[8], bn_v); 87 | h[9] += carry; 88 | carry = round(h[11] / bn_v); 89 | h[11] = remround(h[11], bn_v); 90 | 91 | h[0] = h[0] - carry; 92 | h[3] = h[3] - carry; 93 | h[6] = h[6] - 4 * carry; 94 | h[9] = h[9] - carry; 95 | 96 | carry = round(h[0] / bn_v6); // h0 = 2^53 - 1 97 | h[0] = remround(h[0], bn_v6); // carry = (2^53-1)/6v = 763549741 98 | h[1] += carry; // h1 = v+763549741 = 765515821 99 | carry = round(h[3] / bn_v); // h3 = 2^53 - 1 100 | h[3] = remround(h[3], bn_v); // carry = (2^53-1)/v = 4581298449 101 | h[4] += carry; // h4 = v + 4581298449 = 4583264529 102 | carry = round(h[6] / bn_v6); 103 | h[6] = remround(h[6], bn_v6); 104 | h[7] += carry; 105 | carry = round(h[9] / bn_v); 106 | h[9] = remround(h[9], bn_v); 107 | h[10] += carry; 108 | 109 | carry = round(h[1] / bn_v); // carry = 765515821/v = 389 110 | h[1] = remround(h[1], bn_v); 111 | h[2] += carry; 112 | carry = round(h[4] / bn_v); // carry = 4583264529/v = 2331 113 | h[4] = remround(h[4], bn_v); 114 | h[5] += carry; 115 | carry = round(h[7] / bn_v); 116 | h[7] = remround(h[7], bn_v); 117 | h[8] += carry; 118 | carry = round(h[10] / bn_v); 119 | h[10] = remround(h[10], bn_v); 120 | h[11] += carry; 121 | } 122 | -------------------------------------------------------------------------------- /bn256/fp2e.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: dclxvi-20130329/fp2e.h 3 | * Author: Ruben Niederhagen, Peter Schwabe 4 | * Public Domain 5 | */ 6 | 7 | #ifndef FP2E_H 8 | #define FP2E_H 9 | 10 | #include "fpe.h" 11 | #include "mydouble.h" 12 | #include "scalar.h" 13 | #include 14 | 15 | // Elements from F_{p^2}= F_p[X] / (x^2 - alpha)F_p[X] are represented as aX + b 16 | typedef struct fp2e_struct { 17 | // Arrangement in memory: (b0, a0, b1, a1, ... b11,a11) 18 | mydouble v[24]; 19 | } __attribute__((aligned(16))) fp2e_struct_t; 20 | 21 | typedef fp2e_struct_t fp2e_t[1]; 22 | 23 | void fp2e_to_2fpe(fpe_t ropa, fpe_t ropb, const fp2e_t op); 24 | void _2fpe_to_fp2e(fp2e_t rop, const fpe_t opa, const fpe_t opb); 25 | 26 | #ifdef QHASM 27 | #define fp2e_short_coeffred fp2e_short_coeffred_qhasm 28 | #else 29 | #define fp2e_short_coeffred fp2e_short_coeffred_c 30 | #endif 31 | void fp2e_short_coeffred(fp2e_t rop); 32 | 33 | // Set fp2e_t rop to given value: 34 | void fp2e_set(fp2e_t rop, const fp2e_t op); 35 | 36 | /* Communicate the fact that the fp2e is reduced (and that we don't know anything more about it) */ 37 | void fp2e_isreduced(fp2e_t rop); 38 | 39 | // Set fp2e_t rop to given value contained in the subfield F_p: 40 | void fp2e_set_fpe(fp2e_t rop, const fpe_t op); 41 | 42 | // Set rop to one 43 | void fp2e_setone(fp2e_t rop); 44 | 45 | // Set rop to zero 46 | void fp2e_setzero(fp2e_t rop); 47 | 48 | // Compare for equality: 49 | int fp2e_iseq(const fp2e_t op1, const fp2e_t op2); 50 | 51 | int fp2e_isone(const fp2e_t op); 52 | 53 | int fp2e_iszero(const fp2e_t op); 54 | 55 | void fp2e_cmov(fp2e_t rop, const fp2e_t op, int c); 56 | 57 | #ifdef QHASM 58 | #define fp2e_double fp2e_double_qhasm 59 | #else 60 | #define fp2e_double fp2e_double_c 61 | #endif 62 | // Double an fp2e: 63 | void fp2e_double(fp2e_t rop, const fp2e_t op); 64 | 65 | // Double an fp2e: 66 | #ifdef QHASM 67 | #define fp2e_double2 fp2e_double2_qhasm 68 | #else 69 | #define fp2e_double2 fp2e_double2_c 70 | #endif 71 | void fp2e_double2(fp2e_t rop); 72 | 73 | #ifdef QHASM 74 | #define fp2e_triple fp2e_triple_qhasm 75 | #else 76 | #define fp2e_triple fp2e_triple_c 77 | #endif 78 | // Triple an fp2e: 79 | void fp2e_triple(fp2e_t rop, const fp2e_t op); 80 | 81 | // Triple an fp2e: 82 | #ifdef QHASM 83 | #define fp2e_triple2 fp2e_triple2_qhasm 84 | #else 85 | #define fp2e_triple2 fp2e_triple2_c 86 | #endif 87 | void fp2e_triple2(fp2e_t rop); 88 | 89 | void fp2e_mul_scalar(fp2e_t rop, const fp2e_t op, const int s); 90 | 91 | #ifdef QHASM 92 | #define fp2e_add fp2e_add_qhasm 93 | #else 94 | #define fp2e_add fp2e_add_c 95 | #endif 96 | // Add two fp2e, store result in rop: 97 | void fp2e_add(fp2e_t rop, const fp2e_t op1, const fp2e_t op2); 98 | 99 | // Add rop to up, store result in rop: 100 | #ifdef QHASM 101 | #define fp2e_add2 fp2e_add2_qhasm 102 | #else 103 | #define fp2e_add2 fp2e_add2_c 104 | #endif 105 | void fp2e_add2(fp2e_t rop, const fp2e_t op); 106 | 107 | // Load from mem 108 | void fp2e_load(fp2e_struct_t *rop, const fp2e_t op); 109 | //void fp2e_load(fp2e_t rop, const fp2e_t op); 110 | 111 | // store to mem 112 | void fp2e_store(fp2e_struct_t *rop, const fp2e_t op); 113 | //void fp2e_store(fp2e_t rop, const fp2e_t op); 114 | 115 | #ifdef QHASM 116 | #define fp2e_sub fp2e_sub_qhasm 117 | #else 118 | #define fp2e_sub fp2e_sub_c 119 | #endif 120 | // Subtract op2 from op1, store result in rop: 121 | void fp2e_sub(fp2e_t rop, const fp2e_t op1, const fp2e_t op2); 122 | 123 | #ifdef QHASM 124 | #define fp2e_sub2 fp2e_sub2_qhasm 125 | #else 126 | #define fp2e_sub2 fp2e_sub2_c 127 | #endif 128 | // Subtract op from rop, store result in rop: 129 | void fp2e_sub2(fp2e_t rop, const fp2e_t op); 130 | 131 | #ifdef QHASM 132 | #define fp2e_neg2 fp2e_neg2_qhasm 133 | #else 134 | #define fp2e_neg2 fp2e_neg2_c 135 | #endif 136 | void fp2e_neg2(fp2e_t op); 137 | 138 | #ifdef QHASM 139 | #define fp2e_neg fp2e_neg_qhasm 140 | #else 141 | #define fp2e_neg fp2e_neg_c 142 | #endif 143 | void fp2e_neg(fp2e_t rop, const fp2e_t op); 144 | 145 | #ifdef QHASM 146 | #define fp2e_conjugate fp2e_conjugate_qhasm 147 | #else 148 | #define fp2e_conjugate fp2e_conjugate_c 149 | #endif 150 | // Conjugates: aX+b to -aX+b 151 | void fp2e_conjugate(fp2e_t rop, const fp2e_t op); 152 | 153 | #ifdef QHASM 154 | #define fp2e_mul fp2e_mul_qhasm 155 | #else 156 | #define fp2e_mul fp2e_mul_c 157 | #endif 158 | // Multiply two fp2e, store result in rop: 159 | void fp2e_mul(fp2e_t rop, const fp2e_t op1, const fp2e_t op2); 160 | 161 | // Square an fp2e, store result in rop: 162 | #ifdef QHASM 163 | #define fp2e_square fp2e_square_qhasm 164 | #else 165 | #define fp2e_square fp2e_square_c 166 | #endif 167 | void fp2e_square(fp2e_t rop, const fp2e_t op); 168 | 169 | // Multiply by xi which is used to construct F_p^6 170 | #ifdef QHASM 171 | #define fp2e_mulxi fp2e_mulxi_qhasm 172 | #else 173 | #define fp2e_mulxi fp2e_mulxi_c 174 | #endif 175 | void fp2e_mulxi(fp2e_t rop, const fp2e_t op); 176 | 177 | // Multiple of an fp2e, store result in rop: 178 | #ifdef QHASM 179 | #define fp2e_mul_fpe fp2e_mul_fpe_qhasm 180 | #else 181 | #define fp2e_mul_fpe fp2e_mul_fpe_c 182 | #endif 183 | void fp2e_mul_fpe(fp2e_t rop, const fp2e_t op1, const fpe_t op2); 184 | 185 | #ifdef QHASM 186 | #define fp2e_parallel_coeffmul fp2e_parallel_coeffmul_qhasm 187 | #else 188 | #define fp2e_parallel_coeffmul fp2e_parallel_coeffmul_c 189 | #endif 190 | /* computes (op1->m_a*op2->m_a, op1->m_b*op2->m_b) */ 191 | void fp2e_parallel_coeffmul(fp2e_t rop, const fp2e_t op1, const fp2e_t op2); 192 | 193 | // Inverse multiple of an fp2e, store result in rop: 194 | void fp2e_invert(fp2e_t rop, const fp2e_t op1); 195 | 196 | // Exponentiation: 197 | void fp2e_exp(fp2e_t rop, const fp2e_t op, const scalar_t exp); 198 | 199 | // Square root: 200 | int fp2e_sqrt(fp2e_t rop, const fp2e_t op); 201 | 202 | // Print the element to stdout: 203 | void fp2e_print(FILE *outfile, const fp2e_t op); 204 | 205 | #endif // ifndef FP2E_H 206 | -------------------------------------------------------------------------------- /ibe/ibe_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Alpenhorn Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package ibe 6 | 7 | import ( 8 | "bytes" 9 | "crypto/rand" 10 | "encoding/json" 11 | "math/big" 12 | "testing" 13 | 14 | "vuvuzela.io/crypto/bn256" 15 | ) 16 | 17 | func TestCorrectness(t *testing.T) { 18 | masterPub, masterPriv := Setup(rand.Reader) 19 | 20 | idAlice := Extract(masterPriv, []byte("alice@example.com")) 21 | idBob := Extract(masterPriv, []byte("bob@example.com")) 22 | 23 | msg := make([]byte, 64) 24 | rand.Read(msg) 25 | 26 | c := Encrypt(rand.Reader, masterPub, []byte("bob@example.com"), msg) 27 | 28 | msg2, ok := Decrypt(idBob, c) 29 | if !ok { 30 | t.Fatalf("authentication failed") 31 | } 32 | if bytes.Compare(msg, msg2) != 0 { 33 | t.Fatalf("messages differ: expected=%#v got=%#v", msg, msg2) 34 | } 35 | 36 | _, ok = Decrypt(idAlice, c) 37 | if ok { 38 | t.Fatalf("expected authentication to fail") 39 | } 40 | } 41 | 42 | func TestCiphertextSize(t *testing.T) { 43 | masterPub, _ := Setup(rand.Reader) 44 | 45 | msg := []byte("12345") 46 | c := Encrypt(rand.Reader, masterPub, []byte("bob@example.com"), msg) 47 | bs, _ := c.MarshalBinary() 48 | if len(bs) != len(msg)+Overhead { 49 | t.Fatalf("expecting ciphertext size %d but got %d bytes instead", len(msg)+Overhead, len(bs)) 50 | } 51 | } 52 | 53 | func TestDistributivity(t *testing.T) { 54 | for i := 0; i < 1000; i++ { 55 | secret1, err := rand.Int(rand.Reader, bn256.Order) 56 | if err != nil { 57 | panic(err) 58 | } 59 | secret2, err := rand.Int(rand.Reader, bn256.Order) 60 | if err != nil { 61 | panic(err) 62 | } 63 | public1 := new(bn256.G1).ScalarBaseMult(secret1) 64 | public2 := new(bn256.G1).ScalarBaseMult(secret2) 65 | publicX := new(bn256.G1).Add(public1, public2) 66 | 67 | secret := new(big.Int).Add(secret1, secret2) 68 | publicY := new(bn256.G1).ScalarBaseMult(secret) 69 | 70 | if bytes.Compare(publicX.Marshal(), publicY.Marshal()) != 0 { 71 | t.Fatalf("does not distribute: secret1=%s secret2=%s", secret1, secret2) 72 | } 73 | } 74 | } 75 | 76 | func TestOnion(t *testing.T) { 77 | for i := 0; i < 100; i++ { 78 | masterPub1, masterPriv1 := Setup(rand.Reader) 79 | masterPub2, masterPriv2 := Setup(rand.Reader) 80 | 81 | idAlice1 := Extract(masterPriv1, []byte("alice@example.com")) 82 | idAlice2 := Extract(masterPriv2, []byte("alice@example.com")) 83 | 84 | combinedMasterPublic := new(MasterPublicKey).Aggregate(masterPub1, masterPub2) 85 | combinedIDAlice := new(IdentityPrivateKey).Aggregate(idAlice1, idAlice2) 86 | 87 | msg := make([]byte, 32) 88 | rand.Read(msg) 89 | 90 | c := Encrypt(rand.Reader, combinedMasterPublic, []byte("alice@example.com"), msg) 91 | 92 | msg2, ok := Decrypt(combinedIDAlice, c) 93 | if !ok { 94 | t.Fatalf("decryption failed") 95 | } 96 | 97 | if bytes.Compare(msg, msg2) != 0 { 98 | t.Fatalf("expected the same message") 99 | } 100 | 101 | msgBad, _ := Decrypt(idAlice1, c) 102 | if bytes.Compare(msg, msgBad) == 0 { 103 | t.Fatalf("did not expect the same message") 104 | } 105 | } 106 | } 107 | 108 | func TestMarshalPrivateKey(t *testing.T) { 109 | for i := 0; i < 1000; i++ { 110 | masterPub, masterPriv := Setup(rand.Reader) 111 | 112 | msg := make([]byte, 32) 113 | rand.Read(msg) 114 | ctxt := Encrypt(rand.Reader, masterPub, []byte("alice@example.com"), msg) 115 | 116 | idAlice := Extract(masterPriv, []byte("alice@example.com")) 117 | data, _ := idAlice.MarshalBinary() 118 | id := new(IdentityPrivateKey) 119 | id.UnmarshalBinary(data) 120 | 121 | _, ok := Decrypt(id, ctxt) 122 | if !ok { 123 | t.Fatalf("error decrypting") 124 | } 125 | } 126 | } 127 | 128 | func BenchmarkExtract(b *testing.B) { 129 | _, masterPriv := Setup(rand.Reader) 130 | b.ResetTimer() 131 | for i := 0; i < b.N; i++ { 132 | Extract(masterPriv, []byte("foo@bar.com")) 133 | } 134 | } 135 | 136 | func BenchmarkDecrypt(b *testing.B) { 137 | masterPub, masterPriv := Setup(rand.Reader) 138 | 139 | msg := make([]byte, 32) 140 | rand.Read(msg) 141 | 142 | ctxt := Encrypt(rand.Reader, masterPub, []byte("alice@example.com"), msg) 143 | idAlice := Extract(masterPriv, []byte("alice@example.com")) 144 | 145 | b.ResetTimer() 146 | for i := 0; i < b.N; i++ { 147 | _, ok := Decrypt(idAlice, ctxt) 148 | if !ok { 149 | b.Fatalf("error decrypting") 150 | } 151 | } 152 | } 153 | 154 | // Confirm that decrypting random bytes take the same amount 155 | // of time as decrypting a valid ciphertext. 156 | func BenchmarkDecryptRandom(b *testing.B) { 157 | masterPub, masterPriv := Setup(rand.Reader) 158 | 159 | msg := make([]byte, 32) 160 | rand.Read(msg) 161 | 162 | idAlice := Extract(masterPriv, []byte("alice@example.com")) 163 | 164 | validCtxt := Encrypt(rand.Reader, masterPub, []byte("alice@example.com"), msg) 165 | validBytes, _ := validCtxt.MarshalBinary() 166 | 167 | invalidBytes := make([]byte, len(validBytes)) 168 | rand.Read(invalidBytes) 169 | var invalidCtxt Ciphertext 170 | err := invalidCtxt.UnmarshalBinary(invalidBytes) 171 | if err != nil { 172 | b.Fatalf("failed to unmarshal ciphertext: %s", err) 173 | } 174 | 175 | b.ResetTimer() 176 | for i := 0; i < b.N; i++ { 177 | _, ok := Decrypt(idAlice, invalidCtxt) 178 | if ok { 179 | b.Fatalf("expected decryption to fail") 180 | } 181 | } 182 | } 183 | 184 | func TestMarshalJSON(t *testing.T) { 185 | masterPub, _ := Setup(rand.Reader) 186 | bs, err := json.Marshal(masterPub) 187 | if err != nil { 188 | t.Fatalf("json.Marshal: %s", err) 189 | } 190 | 191 | newMasterPub := new(MasterPublicKey) 192 | err = json.Unmarshal(bs, newMasterPub) 193 | if err != nil { 194 | t.Fatalf("json.Unmarshal: %s", err) 195 | } 196 | 197 | expected, _ := masterPub.MarshalBinary() 198 | actually, _ := newMasterPub.MarshalBinary() 199 | 200 | if !bytes.Equal(expected, actually) { 201 | t.Fatalf("want %x\ngot %x", expected, actually) 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /bn256/linefunction.c: -------------------------------------------------------------------------------- 1 | /* 2 | * File: dclxvi-20130329/linefunction.c 3 | * Author: Ruben Niederhagen, Peter Schwabe 4 | * Public Domain 5 | */ 6 | 7 | #include "curvepoint_fp.h" 8 | #include "fp2e.h" 9 | #include "twistpoint_fp2.h" 10 | 11 | #ifdef N_OPS 12 | unsigned long long linefunction_addctr; 13 | unsigned long long linefunction_doublectr; 14 | #endif 15 | 16 | void linefunction_add_ate( 17 | fp2e_t rop11, 18 | fp2e_t rop12, 19 | fp2e_t rop13, 20 | twistpoint_fp2_t rop2, 21 | const twistpoint_fp2_t op1, 22 | const twistpoint_fp2_t op2, 23 | const curvepoint_fp_t op3, 24 | const fp2e_t r2 // r2 = y^2, see "Faster Computation of Tate Pairings" 25 | ) 26 | 27 | { 28 | #ifdef N_OPS 29 | linefunction_addctr++; 30 | #endif 31 | fp2e_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10; // Temporary variables needed for intermediary results 32 | 33 | fp2e_mul(tmp0, op2->m_x, op1->m_t); /* tmp0 = B = x2 * T1 = x2z1^2*/ 34 | 35 | fp2e_add(tmp1, op2->m_y, op1->m_z); 36 | //fp2e_short_coeffred(tmp1); 37 | fp2e_square(tmp1, tmp1); 38 | fp2e_sub2(tmp1, r2); 39 | fp2e_sub2(tmp1, op1->m_t); 40 | //fp2e_short_coeffred(tmp1); 41 | fp2e_mul(tmp1, tmp1, op1->m_t); /* tmp1 = D = ((y2 + Z1)^2 - R2 - T1)T1 = 2y2z1^3 */ 42 | 43 | fp2e_sub(tmp2, tmp0, op1->m_x); /* tmp2 = H = B - X1 = x2z1^2 - x1*/ 44 | //fp2e_short_coeffred(tmp2); 45 | 46 | fp2e_square(tmp3, tmp2); /* tmp3 = I = H^2 = (x2z1^2 - x1)^2*/ 47 | 48 | fp2e_double(tmp4, tmp3); 49 | fp2e_double2(tmp4); /* tmp4 = E = 4I = 4(x2z1^2 - x1)^2*/ 50 | fp2e_short_coeffred(tmp4); 51 | 52 | fp2e_mul(tmp5, tmp2, tmp4); /* tmp5 = J = HE = 4(x2z1^2 - x1)(x2z1^2 - x1)^2*/ 53 | 54 | fp2e_sub(tmp6, tmp1, op1->m_y); 55 | fp2e_sub2(tmp6, op1->m_y); /* tmp6 = r = 2(D - 2Y1) = (2y2z1^3 - 2y1)*/ 56 | fp2e_short_coeffred(tmp6); 57 | 58 | fp2e_mul(tmp9, tmp6, op2->m_x); /* Needed later: tmp9 = x2(2y2z1^3 - 2y1)*/ 59 | 60 | fp2e_mul(tmp7, op1->m_x, tmp4); /* tmp7 = V = X1*E = 4x1(x2z1^2 - x1)^2*/ 61 | 62 | fp2e_square(rop2->m_x, tmp6); 63 | fp2e_sub2(rop2->m_x, tmp5); 64 | fp2e_sub2(rop2->m_x, tmp7); 65 | fp2e_sub2(rop2->m_x, tmp7); /* X3 = r^2 - J - 2V = (2y2z1^3 - 2y1)^2 - 4(x2z1^2 - x1)(x2z1^2 - x1)^2 - 8x1(x2z1^2 - x1)^2*/ 66 | fp2e_short_coeffred(rop2->m_x); 67 | 68 | fp2e_add(rop2->m_z, op1->m_z, tmp2); 69 | fp2e_short_coeffred(rop2->m_z); 70 | fp2e_square(rop2->m_z, rop2->m_z); 71 | fp2e_sub2(rop2->m_z, op1->m_t); 72 | fp2e_sub2(rop2->m_z, tmp3); /* Z3 = (z1 + H)^2 - T1 - I = 2z1(x2z1^2 - x1) */ 73 | fp2e_short_coeffred(rop2->m_z); 74 | 75 | fp2e_add(tmp10, op2->m_y, rop2->m_z); /* Needed later: tmp10 = y2 + z3*/ 76 | //fp2e_short_coeffred(tmp10); 77 | 78 | fp2e_sub(tmp8, tmp7, rop2->m_x); 79 | //fp2e_short_coeffred(tmp8); 80 | fp2e_mul(tmp8, tmp8, tmp6); 81 | fp2e_mul(tmp0, op1->m_y, tmp5); 82 | fp2e_double2(tmp0); 83 | fp2e_sub(rop2->m_y, tmp8, tmp0); /* Y3 = r(V - X3) - 2Y1*J = (2y2z1^3 - 2y1)(4x1(x2z1^2 - x1)^2 - x3) - 8y1(x2z1^2 - x1)(x2z1^2 - x1)^2*/ 84 | fp2e_short_coeffred(rop2->m_y); 85 | 86 | fp2e_square(rop2->m_t, rop2->m_z); /* T3 = Z3^2 */ 87 | 88 | fp2e_square(tmp10, tmp10); /* tmp10 = (y2 + z3)^2 */ 89 | fp2e_sub2(tmp10, r2); 90 | fp2e_sub2(tmp10, rop2->m_t); 91 | //fp2e_short_coeffred(tmp10); 92 | fp2e_double2(tmp9); 93 | fp2e_sub(rop11, tmp9, tmp10); /* tmp9 = 4x2(y2z1^3 - y1) - 2z3y2 */ 94 | fp2e_short_coeffred(rop11); 95 | 96 | fp2e_mul_fpe(tmp10, rop2->m_z, op3->m_y); /* tmp10 = z3y_Q */ 97 | fp2e_double(rop13, tmp10); 98 | //fp2e_short_coeffred(rop13); 99 | 100 | fp2e_neg(tmp6, tmp6); 101 | fp2e_mul_fpe(tmp1, tmp6, op3->m_x); 102 | fp2e_double(rop12, tmp1); 103 | fp2e_short_coeffred(rop12); 104 | } 105 | 106 | void linefunction_double_ate(fp2e_t rop11, fp2e_t rop12, fp2e_t rop13, twistpoint_fp2_t rop2, const twistpoint_fp2_t op1, const curvepoint_fp_t op3) 107 | { 108 | #ifdef N_OPS 109 | linefunction_doublectr++; 110 | #endif 111 | fp2e_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp7, dummy; // Temporary variables needed for intermediary results 112 | 113 | fp2e_square(tmp0, op1->m_x); /* tmp0 = A = X1^2 = x1^2 */ 114 | fp2e_square(tmp1, op1->m_y); /* tmp1 = B = Y1^2 = y1^2 */ 115 | 116 | fp2e_square(tmp2, tmp1); /* tmp2 = C = B^2 = y1^4 */ 117 | 118 | fp2e_add(tmp3, op1->m_x, tmp1); 119 | //fp2e_short_coeffred(tmp3); 120 | fp2e_square(tmp3, tmp3); 121 | fp2e_sub2(tmp3, tmp0); 122 | fp2e_sub2(tmp3, tmp2); 123 | fp2e_double2(tmp3); /* tmp3 = D = 2(X1 + B)^2 - A - C) = 4x1y1^2 */ 124 | 125 | fp2e_triple(tmp4, tmp0); /* tmp4 = E = 3A = 3x1^2 */ 126 | fp2e_short_coeffred(tmp4); 127 | 128 | fp2e_add(tmp7, tmp4, op1->m_x); /* Needed later */ 129 | //fp2e_short_coeffred(tmp7); 130 | 131 | fp2e_square(tmp5, tmp4); /* tmp5 = G = E^2 = 9x1^4 */ 132 | 133 | fp2e_sub(rop2->m_x, tmp5, tmp3); 134 | fp2e_sub2(rop2->m_x, tmp3); /* X3 = G - 2D = 9x1^4 - 8x1y1^2 */ 135 | fp2e_short_coeffred(rop2->m_x); 136 | 137 | fp2e_add(rop2->m_z, op1->m_y, op1->m_z); 138 | //fp2e_short_coeffred(rop2->m_z); 139 | fp2e_square(rop2->m_z, rop2->m_z); 140 | fp2e_sub2(rop2->m_z, tmp1); 141 | fp2e_sub2(rop2->m_z, op1->m_t); /* Z3 = (Y1 + Z1)^2 - B - T1 = 2y1z1; */ 142 | fp2e_short_coeffred(rop2->m_z); 143 | 144 | fp2e_sub(rop2->m_y, tmp3, rop2->m_x); 145 | fp2e_short_coeffred(rop2->m_y); 146 | fp2e_mul(rop2->m_y, rop2->m_y, tmp4); 147 | fp2e_double(dummy, tmp2); 148 | fp2e_double2(dummy); 149 | fp2e_double2(dummy); 150 | fp2e_sub2(rop2->m_y, dummy); /* Y3 = E(D - X3) - 8C = 3x1^2(4x1y1^2 - X3) - 8y1^4 */ 151 | fp2e_short_coeffred(rop2->m_y); 152 | 153 | fp2e_mul(tmp3, tmp4, op1->m_t); 154 | fp2e_double2(tmp3); 155 | fp2e_neg(tmp3, tmp3); 156 | fp2e_mul_fpe(rop12, tmp3, op3->m_x); /* tmp3 = -6x1^2z1^2 * x_Q */ 157 | 158 | fp2e_square(tmp7, tmp7); 159 | fp2e_sub2(tmp7, tmp0); 160 | fp2e_sub2(tmp7, tmp5); 161 | fp2e_double(dummy, tmp1); 162 | fp2e_double2(dummy); 163 | fp2e_sub(rop11, tmp7, dummy); /* tmp7 = 6x1^3 - 4y1^2 */ 164 | fp2e_short_coeffred(rop11); 165 | 166 | fp2e_mul(tmp0, rop2->m_z, op1->m_t); 167 | fp2e_double2(tmp0); 168 | fp2e_mul_fpe(rop13, tmp0, op3->m_y); 169 | 170 | fp2e_square(rop2->m_t, rop2->m_z); 171 | } 172 | -------------------------------------------------------------------------------- /bn256/checkdouble.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: dclxvi-20130329/checkdouble.h 3 | * Author: Ruben Niederhagen, Peter Schwabe 4 | * Public Domain 5 | */ 6 | 7 | #ifndef CHECKDOUBLE_H 8 | #define CHECKDOUBLE_H 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #define MANTISSA_MAX ((1ULL << 53) - 1) 18 | 19 | class CheckDouble 20 | { 21 | public: 22 | double v; 23 | unsigned long long mmax; 24 | 25 | CheckDouble() 26 | { 27 | v = NAN; 28 | mmax = MANTISSA_MAX; 29 | } 30 | 31 | CheckDouble(const double a) 32 | { 33 | v = a; 34 | mmax = (unsigned long long)fabs(a); 35 | } 36 | 37 | CheckDouble(const CheckDouble &a) 38 | { 39 | v = a.v; 40 | mmax = a.mmax; 41 | } 42 | 43 | CheckDouble(const double a, const unsigned long long int mmax) 44 | { 45 | v = a; 46 | this->mmax = mmax; 47 | } 48 | 49 | CheckDouble operator=(const CheckDouble &a) 50 | { 51 | v = a.v; 52 | mmax = a.mmax; 53 | return *this; 54 | } 55 | 56 | int operator==(const CheckDouble &a) const 57 | { 58 | return v == a.v; 59 | } 60 | 61 | int operator!=(const CheckDouble &a) const 62 | { 63 | return v != a.v; 64 | } 65 | 66 | CheckDouble operator+(const CheckDouble &a) const 67 | { 68 | if ((mmax + a.mmax) > MANTISSA_MAX) { 69 | fprintf(stderr, "Overflow in %lf + %lf\n", v, a.v); 70 | fprintf(stderr, "Maximal values: %llu, %llu\n", mmax, a.mmax); 71 | abort(); 72 | } 73 | return CheckDouble(a.v + v, mmax + a.mmax); 74 | } 75 | 76 | CheckDouble operator+=(const CheckDouble &a) 77 | { 78 | if ((mmax + a.mmax) > MANTISSA_MAX) { 79 | fprintf(stderr, "Overflow in %lf += %lf\n", v, a.v); 80 | fprintf(stderr, "Maximal values: %llu, %llu\n", mmax, a.mmax); 81 | abort(); 82 | } 83 | v += a.v; 84 | mmax += a.mmax; 85 | return *this; 86 | } 87 | 88 | CheckDouble operator-(const CheckDouble &a) const 89 | { 90 | if ((mmax + a.mmax) > MANTISSA_MAX) { 91 | fprintf(stderr, "Overflow in %lf - %lf\n", v, a.v); 92 | fprintf(stderr, "Maximal values: %llu, %llu\n", mmax, a.mmax); 93 | abort(); 94 | } 95 | return CheckDouble(v - a.v, mmax + a.mmax); 96 | } 97 | 98 | CheckDouble operator-=(const CheckDouble &a) 99 | { 100 | if ((mmax + a.mmax) > MANTISSA_MAX) { 101 | fprintf(stderr, "Overflow in %lf += %lf\n", v, a.v); 102 | fprintf(stderr, "Maximal values: %llu, %llu\n", mmax, a.mmax); 103 | abort(); 104 | } 105 | v -= a.v; 106 | mmax += a.mmax; 107 | return *this; 108 | } 109 | 110 | CheckDouble operator-() const 111 | { 112 | return CheckDouble(-v, mmax); 113 | } 114 | 115 | CheckDouble operator*(const CheckDouble &a) const 116 | { 117 | uint64_t l1 = mmax & 0xffffffff; 118 | uint64_t l2 = a.mmax & 0xffffffff; 119 | uint64_t u1 = mmax >> 32; 120 | uint64_t u2 = a.mmax >> 32; 121 | unsigned long long upper = u1 * u2; 122 | if (upper != 0) { 123 | fprintf(stderr, "Overflow in %lf * %lf\n", v, a.v); 124 | fprintf(stderr, "Maximal values: %llu, %llu\n", mmax, a.mmax); 125 | abort(); 126 | } 127 | unsigned long long mid = l1 * u2 + u1 * l2; 128 | unsigned long long lower = l1 * l2; 129 | if (lower >= MANTISSA_MAX) { 130 | fprintf(stderr, "Overflow in %lf * %lf\n", v, a.v); 131 | fprintf(stderr, "Maximal values: %llu, %llu\n", mmax, a.mmax); 132 | abort(); 133 | } 134 | if (mid > (MANTISSA_MAX >> 32)) { 135 | fprintf(stderr, "Overflow in %lf * %lf\n", v, a.v); 136 | fprintf(stderr, "Maximal values: %llu, %llu\n", mmax, a.mmax); 137 | abort(); 138 | } 139 | lower += (mid << 32); 140 | if (lower > MANTISSA_MAX) { 141 | fprintf(stderr, "Overflow in %lf * %lf\n", v, a.v); 142 | fprintf(stderr, "Maximal values: %llu, %llu\n", mmax, a.mmax); 143 | abort(); 144 | } 145 | return CheckDouble(v * a.v, mmax * a.mmax); 146 | } 147 | 148 | CheckDouble operator/(const double &a) const 149 | { 150 | if (mmax / fabs(a) > MANTISSA_MAX) { 151 | fprintf(stderr, "Overflow in %lf / %lf\n", v, a); 152 | fprintf(stderr, "Maximal values: %llu, %lf\n", mmax, a); 153 | abort(); 154 | } 155 | return CheckDouble(v / a, mmax / (unsigned long long)fabs(a) + 1); 156 | } 157 | 158 | CheckDouble operator*=(const int b) 159 | { 160 | CheckDouble op((double)b, abs(b)); 161 | *this = *this * op; 162 | return *this; 163 | } 164 | 165 | /* 166 | friend CheckDouble operator*(const CheckDouble &a,const int b) 167 | { 168 | CheckDouble op((double) b, abs(b)); 169 | return op * a; 170 | } 171 | */ 172 | 173 | friend CheckDouble operator*(const int32_t b, const CheckDouble &a) 174 | { 175 | CheckDouble op((double)b, abs(b)); 176 | return op * a; 177 | } 178 | 179 | friend int operator<(const CheckDouble &op1, const CheckDouble &op2) 180 | { 181 | return op1.v < op2.v; 182 | } 183 | 184 | friend int operator<=(const CheckDouble &op1, const CheckDouble &op2) 185 | { 186 | return op1.v <= op2.v; 187 | } 188 | 189 | friend int operator>(const CheckDouble &op1, const CheckDouble &op2) 190 | { 191 | return op1.v > op2.v; 192 | } 193 | 194 | friend int operator>=(const CheckDouble &op1, const CheckDouble &op2) 195 | { 196 | return op1.v >= op2.v; 197 | } 198 | 199 | friend CheckDouble round(const CheckDouble &a) 200 | { 201 | return CheckDouble(round(a.v), a.mmax); 202 | } 203 | 204 | friend CheckDouble trunc(const CheckDouble &a) 205 | { 206 | return CheckDouble(trunc(a.v), a.mmax); 207 | } 208 | 209 | friend CheckDouble remround(const CheckDouble &a, const double d) 210 | { 211 | double carry = round(a.v / d); 212 | return CheckDouble(a.v - carry * d, (unsigned long long)((d + 1) / 2)); 213 | } 214 | 215 | friend long long ftoll(const CheckDouble &arg) 216 | { 217 | return (long long)arg.v; 218 | } 219 | 220 | friend void setmax(CheckDouble &arg, unsigned long long max) 221 | { 222 | arg.mmax = max; 223 | } 224 | 225 | friend double todouble(const CheckDouble &arg) 226 | { 227 | return arg.v; 228 | } 229 | }; 230 | 231 | int printfoff(...); 232 | 233 | #endif // #ifndef CHECKDOUBLE_H 234 | -------------------------------------------------------------------------------- /bn256/bn256_test.go: -------------------------------------------------------------------------------- 1 | package bn256 2 | 3 | import ( 4 | "bytes" 5 | "crypto/rand" 6 | "math/big" 7 | "testing" 8 | 9 | "golang.org/x/crypto/bn256" 10 | ) 11 | 12 | func TestZeroPowerG1(t *testing.T) { 13 | power := big.NewInt(0) 14 | a := new(G1).ScalarBaseMult(power).Marshal() 15 | b := new(bn256.G1).ScalarBaseMult(power).Marshal() 16 | if !bytes.Equal(a, b) { 17 | t.Errorf("failed at power %s: %x vs %x", power, a, b) 18 | } 19 | } 20 | 21 | func TestZeroPowerG2(t *testing.T) { 22 | power := big.NewInt(0) 23 | a := new(G2).ScalarBaseMult(power).Marshal() 24 | b := new(bn256.G2).ScalarBaseMult(power).Marshal() 25 | if !bytes.Equal(a, b) { 26 | t.Errorf("failed at power %s: %x vs %x", power, a, b) 27 | } 28 | } 29 | 30 | func TestPowersG1(t *testing.T) { 31 | power := big.NewInt(1) 32 | bigOne := big.NewInt(1) 33 | 34 | for i := 0; i < 150; i++ { 35 | a := new(G1).ScalarBaseMult(power).Marshal() 36 | b := new(bn256.G1).ScalarBaseMult(power).Marshal() 37 | if !bytes.Equal(a, b) { 38 | t.Errorf("failed at power %s: %x vs %x", power, a, b) 39 | } 40 | power.Lsh(power, 1) 41 | if i&1 == 1 { 42 | power.Add(power, bigOne) 43 | } 44 | } 45 | } 46 | 47 | func TestMarshalUnmarshalG1(t *testing.T) { 48 | a := new(G1).ScalarBaseMult(big.NewInt(66)) 49 | serialise1 := a.Marshal() 50 | b, ok := new(G1).Unmarshal(serialise1) 51 | if !ok { 52 | t.Fatalf("Unmarshal failed") 53 | } 54 | serialise2 := b.Marshal() 55 | if !bytes.Equal(serialise1, serialise2) { 56 | t.Errorf("Marshal/Unmarshal round trip failed, got: %x want: %x", serialise2, serialise1) 57 | } 58 | } 59 | 60 | func TestPowersG2(t *testing.T) { 61 | power := big.NewInt(1) 62 | bigOne := big.NewInt(1) 63 | 64 | for i := 0; i < 150; i++ { 65 | a := new(G2).ScalarBaseMult(power).Marshal() 66 | b := new(bn256.G2).ScalarBaseMult(power).Marshal() 67 | if !bytes.Equal(a, b) { 68 | t.Errorf("failed at power %s: %x vs %x", power, a, b) 69 | } 70 | power.Lsh(power, 1) 71 | if i&1 == 1 { 72 | power.Add(power, bigOne) 73 | } 74 | } 75 | } 76 | 77 | func TestMarshalUnmarshalG2(t *testing.T) { 78 | a := new(G2).ScalarBaseMult(big.NewInt(66)) 79 | serialise1 := a.Marshal() 80 | b, ok := new(G2).Unmarshal(serialise1) 81 | if !ok { 82 | t.Fatalf("Unmarshal failed") 83 | } 84 | serialise2 := b.Marshal() 85 | if !bytes.Equal(serialise1, serialise2) { 86 | t.Errorf("Marshal/Unmarshal round trip failed, got: %x want: %x", serialise2, serialise1) 87 | } 88 | } 89 | 90 | func TestMarshalUnmarshalGT(t *testing.T) { 91 | a := Pair(new(G1).ScalarBaseMult(big.NewInt(44)), new(G2).ScalarBaseMult(big.NewInt(22))) 92 | serialise1 := a.Marshal() 93 | b, ok := new(GT).Unmarshal(serialise1) 94 | if !ok { 95 | t.Fatalf("Unmarshal failed") 96 | } 97 | serialise2 := b.Marshal() 98 | if !bytes.Equal(serialise1, serialise2) { 99 | t.Errorf("Marshal/Unmarshal round trip failed, got:\n%x\nwant:\n%x", serialise2, serialise1) 100 | } 101 | } 102 | 103 | func TestPairing(t *testing.T) { 104 | a := bn256.Pair(new(bn256.G1).ScalarBaseMult(big.NewInt(2)), new(bn256.G2).ScalarBaseMult(big.NewInt(1))).Marshal() 105 | b := Pair(new(G1).ScalarBaseMult(big.NewInt(2)), new(G2).ScalarBaseMult(big.NewInt(1))).Marshal() 106 | base := Pair(new(G1).ScalarBaseMult(big.NewInt(1)), new(G2).ScalarBaseMult(big.NewInt(1))) 107 | b2 := new(GT).Add(base, base).Marshal() 108 | 109 | if !bytes.Equal(a, b) { 110 | t.Errorf("Pairings differ\ngot: %x\nwant: %x", a, b) 111 | } 112 | if !bytes.Equal(b, b2) { 113 | t.Errorf("Pair(2,1) != 2*Pair(1,1)\ngot: %x\nwant: %x", b, b2) 114 | } 115 | } 116 | 117 | func TestMarshalSame(t *testing.T) { 118 | a := new(G2).ScalarBaseMult(big.NewInt(66)) 119 | aa := new(bn256.G2).ScalarBaseMult(big.NewInt(66)) 120 | if bytes.Compare(a.Marshal(), aa.Marshal()) != 0 { 121 | t.Fatalf("marshalling differs") 122 | } 123 | } 124 | 125 | func BenchmarkUnmarshalG2(b *testing.B) { 126 | a := new(G2).ScalarBaseMult(big.NewInt(66)) 127 | serialise1 := a.Marshal() 128 | b.ResetTimer() 129 | 130 | for i := 0; i < b.N; i++ { 131 | new(G2).Unmarshal(serialise1) 132 | } 133 | } 134 | 135 | func BenchmarkScalarMultG2(b *testing.B) { 136 | r, _ := rand.Int(rand.Reader, Order) 137 | _, x, _ := RandomG2(rand.Reader) 138 | g2 := new(G2) 139 | b.ResetTimer() 140 | for i := 0; i < b.N; i++ { 141 | g2.ScalarMult(x, r) 142 | } 143 | } 144 | 145 | func TestAddG1(t *testing.T) { 146 | for i := 0; i < 500; i++ { 147 | _, x, _ := RandomG1(rand.Reader) 148 | _, y, _ := RandomG1(rand.Reader) 149 | sum := new(G1).Add(x, y) 150 | 151 | xref, _ := new(bn256.G1).Unmarshal(x.Marshal()) 152 | yref, _ := new(bn256.G1).Unmarshal(y.Marshal()) 153 | sumref := new(bn256.G1).Add(xref, yref) 154 | 155 | if !bytes.Equal(sum.Marshal(), sumref.Marshal()) { 156 | t.Fatalf("sums don't match: x=%s y=%s", x, y) 157 | } 158 | } 159 | } 160 | 161 | func TestAddG2(t *testing.T) { 162 | for i := 0; i < 500; i++ { 163 | _, x, _ := RandomG2(rand.Reader) 164 | _, y, _ := RandomG2(rand.Reader) 165 | sum := new(G2).Add(x, y) 166 | 167 | xref, _ := new(bn256.G2).Unmarshal(x.Marshal()) 168 | yref, _ := new(bn256.G2).Unmarshal(y.Marshal()) 169 | sumref := new(bn256.G2).Add(xref, yref) 170 | 171 | if !bytes.Equal(sum.Marshal(), sumref.Marshal()) { 172 | t.Fatalf("sums don't match: x=%s y=%s", x, y) 173 | } 174 | } 175 | } 176 | 177 | // Confirm that elements of G2 are in the n-torsion subgroup. 178 | func TestRandomG2(t *testing.T) { 179 | for i := 0; i < 1000; i++ { 180 | _, g2, _ := RandomG2(rand.Reader) 181 | po := new(twistPoint).Mul(g2.p, Order) 182 | if !po.IsInfinity() { 183 | t.Errorf("pt * Order is not infinity: %v", g2.p) 184 | } 185 | } 186 | } 187 | 188 | func testPrintCgoConstants(t *testing.T) { 189 | // x = (p-3)/4 190 | x := new(big.Int).Sub(p, big.NewInt(3)) 191 | x.Div(x, big.NewInt(4)) 192 | xws := bigToWords(x, p) 193 | t.Logf("(p-3)/4 = %#v", xws) 194 | 195 | // y = (p-1)/2 196 | y := new(big.Int).Sub(p, big.NewInt(1)) 197 | y.Div(y, big.NewInt(2)) 198 | yws := bigToWords(y, p) 199 | t.Logf("(p-1)/2 = %#v", yws) 200 | 201 | // z = p-2 202 | z := new(big.Int).Sub(p, big.NewInt(2)) 203 | zws := bigToWords(z, p) 204 | t.Logf("p-2 = %#v", zws) 205 | 206 | o := new(big.Int).Set(Order) 207 | ows := bigToWords(o, new(big.Int).Exp(Order, big.NewInt(2), nil)) 208 | t.Logf("Order = %#v", ows) 209 | } 210 | -------------------------------------------------------------------------------- /bn256/fpe.c: -------------------------------------------------------------------------------- 1 | /* 2 | * File: dclxvi-20130329/fpe.c 3 | * Author: Ruben Niederhagen, Peter Schwabe 4 | * Public Domain 5 | */ 6 | 7 | #include "fpe.h" 8 | #include "mul.h" 9 | #include "scalar.h" 10 | #include 11 | #include 12 | 13 | extern const scalar_t bn_pminus2; 14 | extern const double bn_v; 15 | extern const double bn_v6; 16 | 17 | void fpe_short_coeffred(fpe_t rop) 18 | { 19 | mydouble carry11 = round(rop->v[11] / bn_v); 20 | rop->v[11] = remround(rop->v[11], bn_v); 21 | rop->v[0] = rop->v[0] - carry11; 22 | rop->v[3] = rop->v[3] - carry11; 23 | rop->v[6] = rop->v[6] - 4 * carry11; 24 | rop->v[9] = rop->v[9] - carry11; 25 | mydouble carry0 = round(rop->v[0] / bn_v6); 26 | mydouble carry1 = round(rop->v[1] / bn_v); 27 | mydouble carry2 = round(rop->v[2] / bn_v); 28 | mydouble carry3 = round(rop->v[3] / bn_v); 29 | mydouble carry4 = round(rop->v[4] / bn_v); 30 | mydouble carry5 = round(rop->v[5] / bn_v); 31 | mydouble carry6 = round(rop->v[6] / bn_v6); 32 | mydouble carry7 = round(rop->v[7] / bn_v); 33 | mydouble carry8 = round(rop->v[8] / bn_v); 34 | mydouble carry9 = round(rop->v[9] / bn_v); 35 | mydouble carry10 = round(rop->v[10] / bn_v); 36 | rop->v[0] = remround(rop->v[0], bn_v6); 37 | rop->v[1] = remround(rop->v[1], bn_v); 38 | rop->v[2] = remround(rop->v[2], bn_v); 39 | rop->v[3] = remround(rop->v[3], bn_v); 40 | rop->v[4] = remround(rop->v[4], bn_v); 41 | rop->v[5] = remround(rop->v[5], bn_v); 42 | rop->v[6] = remround(rop->v[6], bn_v6); 43 | rop->v[7] = remround(rop->v[7], bn_v); 44 | rop->v[8] = remround(rop->v[8], bn_v); 45 | rop->v[9] = remround(rop->v[9], bn_v); 46 | rop->v[10] = remround(rop->v[10], bn_v); 47 | rop->v[1] += carry0; 48 | rop->v[2] += carry1; 49 | rop->v[3] += carry2; 50 | rop->v[4] += carry3; 51 | rop->v[5] += carry4; 52 | rop->v[6] += carry5; 53 | rop->v[7] += carry6; 54 | rop->v[8] += carry7; 55 | rop->v[9] += carry8; 56 | rop->v[10] += carry9; 57 | rop->v[11] += carry10; 58 | } 59 | 60 | // Set fpe_t rop to given value: 61 | void fpe_set(fpe_t rop, const fpe_t op) 62 | { 63 | int i; 64 | for (i = 0; i < 12; i++) 65 | rop->v[i] = op->v[i]; 66 | } 67 | 68 | /* Communicate the fact that the fpe is reduced (and that we don't know anything more about it) */ 69 | void fpe_isreduced(fpe_t rop) 70 | { 71 | setmax(rop->v[0], (long)bn_v6 / 2); 72 | setmax(rop->v[6], (long)bn_v6 / 2); 73 | 74 | setmax(rop->v[1], (long)bn_v / 2); 75 | setmax(rop->v[3], (long)bn_v / 2); 76 | setmax(rop->v[4], (long)bn_v / 2); 77 | setmax(rop->v[7], (long)bn_v / 2); 78 | setmax(rop->v[9], (long)bn_v / 2); 79 | setmax(rop->v[10], (long)bn_v / 2); 80 | 81 | //XXX: Change additive constant: 82 | setmax(rop->v[2], (long)bn_v / 2 + 2331); 83 | setmax(rop->v[5], (long)bn_v / 2 + 2331); 84 | setmax(rop->v[8], (long)bn_v / 2 + 2331); 85 | setmax(rop->v[11], (long)bn_v / 2 + 2331); 86 | } 87 | 88 | // Set fpe_t rop to value given in double array of length 12 89 | void fpe_set_doublearray(fpe_t rop, const mydouble op[12]) 90 | { 91 | int i; 92 | for (i = 0; i < 12; i++) 93 | rop->v[i] = op[i]; 94 | } 95 | 96 | // Set rop to one 97 | void fpe_setone(fpe_t rop) 98 | { 99 | int i; 100 | for (i = 1; i < 12; i++) 101 | rop->v[i] = 0.; 102 | rop->v[0] = 1; 103 | } 104 | 105 | // Set rop to zero 106 | void fpe_setzero(fpe_t rop) 107 | { 108 | int i; 109 | for (i = 0; i < 12; i++) 110 | rop->v[i] = 0.; 111 | } 112 | 113 | int fpe_iseq(const fpe_t op1, const fpe_t op2) 114 | { 115 | fpe_t t; 116 | fpe_sub(t, op1, op2); 117 | return fpe_iszero(t); 118 | } 119 | 120 | int fpe_isone(const fpe_t op) 121 | { 122 | fpe_t t; 123 | int i; 124 | for (i = 1; i < 12; i++) 125 | t->v[i] = op->v[i]; 126 | t->v[0] = op->v[0] - 1.; 127 | return fpe_iszero(t); 128 | } 129 | 130 | int fpe_iszero(const fpe_t op) 131 | { 132 | fpe_t t; 133 | double d; 134 | int i; 135 | unsigned long long tr = 0; 136 | unsigned int differentbits = 0; 137 | for (i = 0; i < 12; i++) 138 | t->v[i] = op->v[i]; 139 | coeffred_round_par(t->v); 140 | 141 | //Constant-time comparison 142 | double zero = 0.; 143 | unsigned long long *zp = (unsigned long long *)&zero; 144 | ; 145 | unsigned long long *tp; 146 | 147 | for (i = 0; i < 12; i++) { 148 | d = todouble(t->v[i]); 149 | tp = (unsigned long long *)&d; 150 | tr |= (*tp ^ *zp); 151 | } 152 | for (i = 0; i < 8; i++) 153 | differentbits |= i[(unsigned char *)&tr]; 154 | 155 | return 1 & ((differentbits - 1) >> 8); 156 | } 157 | 158 | // Compute the negative of an fpe 159 | void fpe_neg(fpe_t rop, const fpe_t op) 160 | { 161 | int i; 162 | for (i = 0; i < 12; i++) 163 | rop->v[i] = -op->v[i]; 164 | } 165 | 166 | // Double an fpe: 167 | void fpe_double(fpe_t rop, const fpe_t op) 168 | { 169 | int i; 170 | for (i = 0; i < 12; i++) 171 | rop->v[i] = op->v[i] * 2; 172 | } 173 | 174 | // Double an fpe: 175 | void fpe_triple(fpe_t rop, const fpe_t op) 176 | { 177 | int i; 178 | for (i = 0; i < 12; i++) 179 | rop->v[i] = op->v[i] * 3; 180 | } 181 | 182 | // Add two fpe, store result in rop: 183 | void fpe_add(fpe_t rop, const fpe_t op1, const fpe_t op2) 184 | { 185 | int i; 186 | for (i = 0; i < 12; i++) 187 | rop->v[i] = op1->v[i] + op2->v[i]; 188 | } 189 | 190 | // Subtract op2 from op1, store result in rop: 191 | void fpe_sub(fpe_t rop, const fpe_t op1, const fpe_t op2) 192 | { 193 | int i; 194 | for (i = 0; i < 12; i++) 195 | rop->v[i] = op1->v[i] - op2->v[i]; 196 | } 197 | 198 | // Multiply two fpe, store result in rop: 199 | #ifndef QHASM 200 | void fpe_mul_c(fpe_t rop, const fpe_t op1, const fpe_t op2) 201 | { 202 | mydouble h[24]; 203 | polymul(h, op1->v, op2->v); 204 | degred(h); 205 | coeffred_round_par(h); 206 | int i; 207 | for (i = 0; i < 12; i++) 208 | rop->v[i] = h[i]; 209 | } 210 | #endif 211 | 212 | // Square an fpe, store result in rop: 213 | void fpe_square(fpe_t rop, const fpe_t op) 214 | { 215 | /* Not used during pairing computation */ 216 | fpe_mul(rop, op, op); 217 | } 218 | 219 | // Compute inverse of an fpe, store result in rop: 220 | void fpe_invert(fpe_t rop, const fpe_t op1) 221 | { 222 | fpe_set(rop, op1); 223 | int i; 224 | for (i = 254; i >= 0; i--) { 225 | fpe_mul(rop, rop, rop); 226 | if (scalar_getbit(bn_pminus2, i)) 227 | fpe_mul(rop, rop, op1); 228 | } 229 | } 230 | 231 | // Print the element to stdout: 232 | void fpe_print(FILE *outfile, const fpe_t op) 233 | { 234 | int i; 235 | for (i = 0; i < 11; i++) 236 | fprintf(outfile, "%10lf, ", todouble(op->v[i])); 237 | fprintf(outfile, "%10lf", todouble(op->v[11])); 238 | } 239 | -------------------------------------------------------------------------------- /bn256ref/twist.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package bn256ref 6 | 7 | import ( 8 | "math/big" 9 | ) 10 | 11 | // twistPoint implements the elliptic curve y²=x³+3/ξ over GF(p²). Points are 12 | // kept in Jacobian form and t=z² when valid. The group G₂ is the set of 13 | // n-torsion points of this curve over GF(p²) (where n = Order) 14 | type twistPoint struct { 15 | x, y, z, t *GFp2 16 | } 17 | 18 | var twistB = &GFp2{ 19 | bigFromBase10("6500054969564660373279643874235990574282535810762300357187714502686418407178"), 20 | bigFromBase10("45500384786952622612957507119651934019977750675336102500314001518804928850249"), 21 | } 22 | 23 | // twistGen is the generator of group G₂. 24 | var twistGen = &twistPoint{ 25 | &GFp2{ 26 | bigFromBase10("21167961636542580255011770066570541300993051739349375019639421053990175267184"), 27 | bigFromBase10("64746500191241794695844075326670126197795977525365406531717464316923369116492"), 28 | }, 29 | &GFp2{ 30 | bigFromBase10("20666913350058776956210519119118544732556678129809273996262322366050359951122"), 31 | bigFromBase10("17778617556404439934652658462602675281523610326338642107814333856843981424549"), 32 | }, 33 | &GFp2{ 34 | bigFromBase10("0"), 35 | bigFromBase10("1"), 36 | }, 37 | &GFp2{ 38 | bigFromBase10("0"), 39 | bigFromBase10("1"), 40 | }, 41 | } 42 | 43 | func newTwistPoint(pool *bnPool) *twistPoint { 44 | return &twistPoint{ 45 | newGFp2(pool), 46 | newGFp2(pool), 47 | newGFp2(pool), 48 | newGFp2(pool), 49 | } 50 | } 51 | 52 | func (c *twistPoint) String() string { 53 | return "(" + c.x.String() + ", " + c.y.String() + ", " + c.z.String() + ")" 54 | } 55 | 56 | func (c *twistPoint) Put(pool *bnPool) { 57 | c.x.Put(pool) 58 | c.y.Put(pool) 59 | c.z.Put(pool) 60 | c.t.Put(pool) 61 | } 62 | 63 | func (c *twistPoint) Set(a *twistPoint) { 64 | c.x.Set(a.x) 65 | c.y.Set(a.y) 66 | c.z.Set(a.z) 67 | c.t.Set(a.t) 68 | } 69 | 70 | // IsOnCurve returns true iff c is on the curve where c must be in affine form. 71 | func (c *twistPoint) IsOnCurve() bool { 72 | pool := new(bnPool) 73 | yy := newGFp2(pool).Square(c.y, pool) 74 | xxx := newGFp2(pool).Square(c.x, pool) 75 | xxx.Mul(xxx, c.x, pool) 76 | yy.Sub(yy, xxx) 77 | yy.Sub(yy, twistB) 78 | yy.Minimal() 79 | return yy.x.Sign() == 0 && yy.y.Sign() == 0 80 | } 81 | 82 | func (c *twistPoint) SetInfinity() { 83 | c.z.SetZero() 84 | } 85 | 86 | func (c *twistPoint) IsInfinity() bool { 87 | return c.z.IsZero() 88 | } 89 | 90 | func (c *twistPoint) Add(a, b *twistPoint, pool *bnPool) { 91 | // For additional comments, see the same function in curve.go. 92 | 93 | if a.IsInfinity() { 94 | c.Set(b) 95 | return 96 | } 97 | if b.IsInfinity() { 98 | c.Set(a) 99 | return 100 | } 101 | 102 | // See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/addition/add-2007-bl.op3 103 | z1z1 := newGFp2(pool).Square(a.z, pool) 104 | z2z2 := newGFp2(pool).Square(b.z, pool) 105 | u1 := newGFp2(pool).Mul(a.x, z2z2, pool) 106 | u2 := newGFp2(pool).Mul(b.x, z1z1, pool) 107 | 108 | t := newGFp2(pool).Mul(b.z, z2z2, pool) 109 | s1 := newGFp2(pool).Mul(a.y, t, pool) 110 | 111 | t.Mul(a.z, z1z1, pool) 112 | s2 := newGFp2(pool).Mul(b.y, t, pool) 113 | 114 | h := newGFp2(pool).Sub(u2, u1) 115 | xEqual := h.IsZero() 116 | 117 | t.Add(h, h) 118 | i := newGFp2(pool).Square(t, pool) 119 | j := newGFp2(pool).Mul(h, i, pool) 120 | 121 | t.Sub(s2, s1) 122 | yEqual := t.IsZero() 123 | if xEqual && yEqual { 124 | c.Double(a, pool) 125 | return 126 | } 127 | r := newGFp2(pool).Add(t, t) 128 | 129 | v := newGFp2(pool).Mul(u1, i, pool) 130 | 131 | t4 := newGFp2(pool).Square(r, pool) 132 | t.Add(v, v) 133 | t6 := newGFp2(pool).Sub(t4, j) 134 | c.x.Sub(t6, t) 135 | 136 | t.Sub(v, c.x) // t7 137 | t4.Mul(s1, j, pool) // t8 138 | t6.Add(t4, t4) // t9 139 | t4.Mul(r, t, pool) // t10 140 | c.y.Sub(t4, t6) 141 | 142 | t.Add(a.z, b.z) // t11 143 | t4.Square(t, pool) // t12 144 | t.Sub(t4, z1z1) // t13 145 | t4.Sub(t, z2z2) // t14 146 | c.z.Mul(t4, h, pool) 147 | 148 | z1z1.Put(pool) 149 | z2z2.Put(pool) 150 | u1.Put(pool) 151 | u2.Put(pool) 152 | t.Put(pool) 153 | s1.Put(pool) 154 | s2.Put(pool) 155 | h.Put(pool) 156 | i.Put(pool) 157 | j.Put(pool) 158 | r.Put(pool) 159 | v.Put(pool) 160 | t4.Put(pool) 161 | t6.Put(pool) 162 | } 163 | 164 | func (c *twistPoint) Double(a *twistPoint, pool *bnPool) { 165 | // See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/doubling/dbl-2009-l.op3 166 | A := newGFp2(pool).Square(a.x, pool) 167 | B := newGFp2(pool).Square(a.y, pool) 168 | C := newGFp2(pool).Square(B, pool) 169 | 170 | t := newGFp2(pool).Add(a.x, B) 171 | t2 := newGFp2(pool).Square(t, pool) 172 | t.Sub(t2, A) 173 | t2.Sub(t, C) 174 | d := newGFp2(pool).Add(t2, t2) 175 | t.Add(A, A) 176 | e := newGFp2(pool).Add(t, A) 177 | f := newGFp2(pool).Square(e, pool) 178 | 179 | t.Add(d, d) 180 | c.x.Sub(f, t) 181 | 182 | t.Add(C, C) 183 | t2.Add(t, t) 184 | t.Add(t2, t2) 185 | c.y.Sub(d, c.x) 186 | t2.Mul(e, c.y, pool) 187 | c.y.Sub(t2, t) 188 | 189 | t.Mul(a.y, a.z, pool) 190 | c.z.Add(t, t) 191 | 192 | A.Put(pool) 193 | B.Put(pool) 194 | C.Put(pool) 195 | t.Put(pool) 196 | t2.Put(pool) 197 | d.Put(pool) 198 | e.Put(pool) 199 | f.Put(pool) 200 | } 201 | 202 | func (c *twistPoint) Mul(a *twistPoint, scalar *big.Int, pool *bnPool) *twistPoint { 203 | sum := newTwistPoint(pool) 204 | sum.SetInfinity() 205 | t := newTwistPoint(pool) 206 | 207 | for i := scalar.BitLen(); i >= 0; i-- { 208 | t.Double(sum, pool) 209 | if scalar.Bit(i) != 0 { 210 | sum.Add(t, a, pool) 211 | } else { 212 | sum.Set(t) 213 | } 214 | } 215 | 216 | c.Set(sum) 217 | sum.Put(pool) 218 | t.Put(pool) 219 | return c 220 | } 221 | 222 | // TODO(DL): what should MakeAffine do when c is Infinity? 223 | func (c *twistPoint) MakeAffine(pool *bnPool) *twistPoint { 224 | if c.z.IsOne() { 225 | return c 226 | } 227 | 228 | zInv := newGFp2(pool).Invert(c.z, pool) 229 | t := newGFp2(pool).Mul(c.y, zInv, pool) 230 | zInv2 := newGFp2(pool).Square(zInv, pool) 231 | c.y.Mul(t, zInv2, pool) 232 | t.Mul(c.x, zInv2, pool) 233 | c.x.Set(t) 234 | c.z.SetOne() 235 | c.t.SetOne() 236 | 237 | zInv.Put(pool) 238 | t.Put(pool) 239 | zInv2.Put(pool) 240 | 241 | return c 242 | } 243 | 244 | func (c *twistPoint) Negative(a *twistPoint, pool *bnPool) { 245 | c.x.Set(a.x) 246 | c.y.SetZero() 247 | c.y.Sub(c.y, a.y) 248 | c.z.Set(a.z) 249 | c.t.SetZero() 250 | } 251 | -------------------------------------------------------------------------------- /bn256ref/curve.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package bn256ref 6 | 7 | import ( 8 | "math/big" 9 | ) 10 | 11 | // curvePoint implements the elliptic curve y²=x³+3. Points are kept in 12 | // Jacobian form and t=z² when valid. G₁ is the set of points of this curve on 13 | // GF(p). 14 | type curvePoint struct { 15 | x, y, z, t *big.Int 16 | } 17 | 18 | var curveB = new(big.Int).SetInt64(3) 19 | 20 | // curveGen is the generator of G₁. 21 | var curveGen = &curvePoint{ 22 | new(big.Int).SetInt64(1), 23 | new(big.Int).SetInt64(-2), 24 | new(big.Int).SetInt64(1), 25 | new(big.Int).SetInt64(1), 26 | } 27 | 28 | func newCurvePoint(pool *bnPool) *curvePoint { 29 | return &curvePoint{ 30 | pool.Get(), 31 | pool.Get(), 32 | pool.Get(), 33 | pool.Get(), 34 | } 35 | } 36 | 37 | func (c *curvePoint) String() string { 38 | c.MakeAffine(new(bnPool)) 39 | return "(" + c.x.String() + ", " + c.y.String() + ")" 40 | } 41 | 42 | func (c *curvePoint) Put(pool *bnPool) { 43 | pool.Put(c.x) 44 | pool.Put(c.y) 45 | pool.Put(c.z) 46 | pool.Put(c.t) 47 | } 48 | 49 | func (c *curvePoint) Set(a *curvePoint) { 50 | c.x.Set(a.x) 51 | c.y.Set(a.y) 52 | c.z.Set(a.z) 53 | c.t.Set(a.t) 54 | } 55 | 56 | // IsOnCurve returns true iff c is on the curve where c must be in affine form. 57 | func (c *curvePoint) IsOnCurve() bool { 58 | yy := new(big.Int).Mul(c.y, c.y) 59 | xxx := new(big.Int).Mul(c.x, c.x) 60 | xxx.Mul(xxx, c.x) 61 | yy.Sub(yy, xxx) 62 | yy.Sub(yy, curveB) 63 | if yy.Sign() < 0 || yy.Cmp(p) >= 0 { 64 | yy.Mod(yy, p) 65 | } 66 | return yy.Sign() == 0 67 | } 68 | 69 | func (c *curvePoint) SetInfinity() { 70 | c.z.SetInt64(0) 71 | } 72 | 73 | func (c *curvePoint) IsInfinity() bool { 74 | return c.z.Sign() == 0 75 | } 76 | 77 | func (c *curvePoint) Add(a, b *curvePoint, pool *bnPool) { 78 | if a.IsInfinity() { 79 | c.Set(b) 80 | return 81 | } 82 | if b.IsInfinity() { 83 | c.Set(a) 84 | return 85 | } 86 | 87 | // See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/addition/add-2007-bl.op3 88 | 89 | // Normalize the points by replacing a = [x1:y1:z1] and b = [x2:y2:z2] 90 | // by [u1:s1:z1·z2] and [u2:s2:z1·z2] 91 | // where u1 = x1·z2², s1 = y1·z2³ and u1 = x2·z1², s2 = y2·z1³ 92 | z1z1 := pool.Get().Mul(a.z, a.z) 93 | z1z1.Mod(z1z1, p) 94 | z2z2 := pool.Get().Mul(b.z, b.z) 95 | z2z2.Mod(z2z2, p) 96 | u1 := pool.Get().Mul(a.x, z2z2) 97 | u1.Mod(u1, p) 98 | u2 := pool.Get().Mul(b.x, z1z1) 99 | u2.Mod(u2, p) 100 | 101 | t := pool.Get().Mul(b.z, z2z2) 102 | t.Mod(t, p) 103 | s1 := pool.Get().Mul(a.y, t) 104 | s1.Mod(s1, p) 105 | 106 | t.Mul(a.z, z1z1) 107 | t.Mod(t, p) 108 | s2 := pool.Get().Mul(b.y, t) 109 | s2.Mod(s2, p) 110 | 111 | // Compute x = (2h)²(s²-u1-u2) 112 | // where s = (s2-s1)/(u2-u1) is the slope of the line through 113 | // (u1,s1) and (u2,s2). The extra factor 2h = 2(u2-u1) comes from the value of z below. 114 | // This is also: 115 | // 4(s2-s1)² - 4h²(u1+u2) = 4(s2-s1)² - 4h³ - 4h²(2u1) 116 | // = r² - j - 2v 117 | // with the notations below. 118 | h := pool.Get().Sub(u2, u1) 119 | xEqual := h.Sign() == 0 120 | 121 | t.Add(h, h) 122 | // i = 4h² 123 | i := pool.Get().Mul(t, t) 124 | i.Mod(i, p) 125 | // j = 4h³ 126 | j := pool.Get().Mul(h, i) 127 | j.Mod(j, p) 128 | 129 | t.Sub(s2, s1) 130 | yEqual := t.Sign() == 0 131 | if xEqual && yEqual { 132 | c.Double(a, pool) 133 | return 134 | } 135 | r := pool.Get().Add(t, t) 136 | 137 | v := pool.Get().Mul(u1, i) 138 | v.Mod(v, p) 139 | 140 | // t4 = 4(s2-s1)² 141 | t4 := pool.Get().Mul(r, r) 142 | t4.Mod(t4, p) 143 | t.Add(v, v) 144 | t6 := pool.Get().Sub(t4, j) 145 | c.x.Sub(t6, t) 146 | 147 | // Set y = -(2h)³(s1 + s*(x/4h²-u1)) 148 | // This is also 149 | // y = - 2·s1·j - (s2-s1)(2x - 2i·u1) = r(v-x) - 2·s1·j 150 | t.Sub(v, c.x) // t7 151 | t4.Mul(s1, j) // t8 152 | t4.Mod(t4, p) 153 | t6.Add(t4, t4) // t9 154 | t4.Mul(r, t) // t10 155 | t4.Mod(t4, p) 156 | c.y.Sub(t4, t6) 157 | 158 | // Set z = 2(u2-u1)·z1·z2 = 2h·z1·z2 159 | t.Add(a.z, b.z) // t11 160 | t4.Mul(t, t) // t12 161 | t4.Mod(t4, p) 162 | t.Sub(t4, z1z1) // t13 163 | t4.Sub(t, z2z2) // t14 164 | c.z.Mul(t4, h) 165 | c.z.Mod(c.z, p) 166 | 167 | pool.Put(z1z1) 168 | pool.Put(z2z2) 169 | pool.Put(u1) 170 | pool.Put(u2) 171 | pool.Put(t) 172 | pool.Put(s1) 173 | pool.Put(s2) 174 | pool.Put(h) 175 | pool.Put(i) 176 | pool.Put(j) 177 | pool.Put(r) 178 | pool.Put(v) 179 | pool.Put(t4) 180 | pool.Put(t6) 181 | } 182 | 183 | func (c *curvePoint) Double(a *curvePoint, pool *bnPool) { 184 | // See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/doubling/dbl-2009-l.op3 185 | A := pool.Get().Mul(a.x, a.x) 186 | A.Mod(A, p) 187 | B := pool.Get().Mul(a.y, a.y) 188 | B.Mod(B, p) 189 | C := pool.Get().Mul(B, B) 190 | C.Mod(C, p) 191 | 192 | t := pool.Get().Add(a.x, B) 193 | t2 := pool.Get().Mul(t, t) 194 | t2.Mod(t2, p) 195 | t.Sub(t2, A) 196 | t2.Sub(t, C) 197 | d := pool.Get().Add(t2, t2) 198 | t.Add(A, A) 199 | e := pool.Get().Add(t, A) 200 | f := pool.Get().Mul(e, e) 201 | f.Mod(f, p) 202 | 203 | t.Add(d, d) 204 | c.x.Sub(f, t) 205 | 206 | t.Add(C, C) 207 | t2.Add(t, t) 208 | t.Add(t2, t2) 209 | c.y.Sub(d, c.x) 210 | t2.Mul(e, c.y) 211 | t2.Mod(t2, p) 212 | c.y.Sub(t2, t) 213 | 214 | t.Mul(a.y, a.z) 215 | t.Mod(t, p) 216 | c.z.Add(t, t) 217 | 218 | pool.Put(A) 219 | pool.Put(B) 220 | pool.Put(C) 221 | pool.Put(t) 222 | pool.Put(t2) 223 | pool.Put(d) 224 | pool.Put(e) 225 | pool.Put(f) 226 | } 227 | 228 | func (c *curvePoint) Mul(a *curvePoint, scalar *big.Int, pool *bnPool) *curvePoint { 229 | sum := newCurvePoint(pool) 230 | sum.SetInfinity() 231 | t := newCurvePoint(pool) 232 | 233 | for i := scalar.BitLen(); i >= 0; i-- { 234 | t.Double(sum, pool) 235 | if scalar.Bit(i) != 0 { 236 | sum.Add(t, a, pool) 237 | } else { 238 | sum.Set(t) 239 | } 240 | } 241 | 242 | c.Set(sum) 243 | sum.Put(pool) 244 | t.Put(pool) 245 | return c 246 | } 247 | 248 | func (c *curvePoint) MakeAffine(pool *bnPool) *curvePoint { 249 | if words := c.z.Bits(); len(words) == 1 && words[0] == 1 { 250 | return c 251 | } 252 | 253 | zInv := pool.Get().ModInverse(c.z, p) 254 | t := pool.Get().Mul(c.y, zInv) 255 | t.Mod(t, p) 256 | zInv2 := pool.Get().Mul(zInv, zInv) 257 | zInv2.Mod(zInv2, p) 258 | c.y.Mul(t, zInv2) 259 | c.y.Mod(c.y, p) 260 | t.Mul(c.x, zInv2) 261 | t.Mod(t, p) 262 | c.x.Set(t) 263 | c.z.SetInt64(1) 264 | c.t.SetInt64(1) 265 | 266 | pool.Put(zInv) 267 | pool.Put(t) 268 | pool.Put(zInv2) 269 | 270 | return c 271 | } 272 | 273 | func (c *curvePoint) Negative(a *curvePoint) { 274 | c.x.Set(a.x) 275 | c.y.Neg(a.y) 276 | c.z.Set(a.z) 277 | c.t.SetInt64(0) 278 | } 279 | -------------------------------------------------------------------------------- /bn256ref/gfp6.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package bn256ref 6 | 7 | // For details of the algorithms used, see "Multiplication and Squaring on 8 | // Pairing-Friendly Fields, Devegili et al. 9 | // http://eprint.iacr.org/2006/471.pdf. 10 | 11 | import ( 12 | "math/big" 13 | ) 14 | 15 | // gfP6 implements the field of size p⁶ as a cubic extension of GFp2 where τ³=ξ 16 | // and ξ=i+3. 17 | type gfP6 struct { 18 | x, y, z *GFp2 // value is xτ² + yτ + z 19 | } 20 | 21 | func newGFp6(pool *bnPool) *gfP6 { 22 | return &gfP6{newGFp2(pool), newGFp2(pool), newGFp2(pool)} 23 | } 24 | 25 | func (e *gfP6) String() string { 26 | return "(" + e.x.String() + "," + e.y.String() + "," + e.z.String() + ")" 27 | } 28 | 29 | func (e *gfP6) Put(pool *bnPool) { 30 | e.x.Put(pool) 31 | e.y.Put(pool) 32 | e.z.Put(pool) 33 | } 34 | 35 | func (e *gfP6) Set(a *gfP6) *gfP6 { 36 | e.x.Set(a.x) 37 | e.y.Set(a.y) 38 | e.z.Set(a.z) 39 | return e 40 | } 41 | 42 | func (e *gfP6) SetZero() *gfP6 { 43 | e.x.SetZero() 44 | e.y.SetZero() 45 | e.z.SetZero() 46 | return e 47 | } 48 | 49 | func (e *gfP6) SetOne() *gfP6 { 50 | e.x.SetZero() 51 | e.y.SetZero() 52 | e.z.SetOne() 53 | return e 54 | } 55 | 56 | func (e *gfP6) Minimal() { 57 | e.x.Minimal() 58 | e.y.Minimal() 59 | e.z.Minimal() 60 | } 61 | 62 | func (e *gfP6) IsZero() bool { 63 | return e.x.IsZero() && e.y.IsZero() && e.z.IsZero() 64 | } 65 | 66 | func (e *gfP6) IsOne() bool { 67 | return e.x.IsZero() && e.y.IsZero() && e.z.IsOne() 68 | } 69 | 70 | func (e *gfP6) Negative(a *gfP6) *gfP6 { 71 | e.x.Negative(a.x) 72 | e.y.Negative(a.y) 73 | e.z.Negative(a.z) 74 | return e 75 | } 76 | 77 | func (e *gfP6) Frobenius(a *gfP6, pool *bnPool) *gfP6 { 78 | e.x.Conjugate(a.x) 79 | e.y.Conjugate(a.y) 80 | e.z.Conjugate(a.z) 81 | 82 | e.x.Mul(e.x, xiTo2PMinus2Over3, pool) 83 | e.y.Mul(e.y, xiToPMinus1Over3, pool) 84 | return e 85 | } 86 | 87 | // FrobeniusP2 computes (xτ²+yτ+z)^(p²) = xτ^(2p²) + yτ^(p²) + z 88 | func (e *gfP6) FrobeniusP2(a *gfP6) *gfP6 { 89 | // τ^(2p²) = τ²τ^(2p²-2) = τ²ξ^((2p²-2)/3) 90 | e.x.MulScalar(a.x, xiTo2PSquaredMinus2Over3) 91 | // τ^(p²) = ττ^(p²-1) = τξ^((p²-1)/3) 92 | e.y.MulScalar(a.y, xiToPSquaredMinus1Over3) 93 | e.z.Set(a.z) 94 | return e 95 | } 96 | 97 | func (e *gfP6) Add(a, b *gfP6) *gfP6 { 98 | e.x.Add(a.x, b.x) 99 | e.y.Add(a.y, b.y) 100 | e.z.Add(a.z, b.z) 101 | return e 102 | } 103 | 104 | func (e *gfP6) Sub(a, b *gfP6) *gfP6 { 105 | e.x.Sub(a.x, b.x) 106 | e.y.Sub(a.y, b.y) 107 | e.z.Sub(a.z, b.z) 108 | return e 109 | } 110 | 111 | func (e *gfP6) Double(a *gfP6) *gfP6 { 112 | e.x.Double(a.x) 113 | e.y.Double(a.y) 114 | e.z.Double(a.z) 115 | return e 116 | } 117 | 118 | func (e *gfP6) Mul(a, b *gfP6, pool *bnPool) *gfP6 { 119 | // "Multiplication and Squaring on Pairing-Friendly Fields" 120 | // Section 4, Karatsuba method. 121 | // http://eprint.iacr.org/2006/471.pdf 122 | 123 | v0 := newGFp2(pool) 124 | v0.Mul(a.z, b.z, pool) 125 | v1 := newGFp2(pool) 126 | v1.Mul(a.y, b.y, pool) 127 | v2 := newGFp2(pool) 128 | v2.Mul(a.x, b.x, pool) 129 | 130 | t0 := newGFp2(pool) 131 | t0.Add(a.x, a.y) 132 | t1 := newGFp2(pool) 133 | t1.Add(b.x, b.y) 134 | tz := newGFp2(pool) 135 | tz.Mul(t0, t1, pool) 136 | 137 | tz.Sub(tz, v1) 138 | tz.Sub(tz, v2) 139 | tz.MulXi(tz, pool) 140 | tz.Add(tz, v0) 141 | 142 | t0.Add(a.y, a.z) 143 | t1.Add(b.y, b.z) 144 | ty := newGFp2(pool) 145 | ty.Mul(t0, t1, pool) 146 | ty.Sub(ty, v0) 147 | ty.Sub(ty, v1) 148 | t0.MulXi(v2, pool) 149 | ty.Add(ty, t0) 150 | 151 | t0.Add(a.x, a.z) 152 | t1.Add(b.x, b.z) 153 | tx := newGFp2(pool) 154 | tx.Mul(t0, t1, pool) 155 | tx.Sub(tx, v0) 156 | tx.Add(tx, v1) 157 | tx.Sub(tx, v2) 158 | 159 | e.x.Set(tx) 160 | e.y.Set(ty) 161 | e.z.Set(tz) 162 | 163 | t0.Put(pool) 164 | t1.Put(pool) 165 | tx.Put(pool) 166 | ty.Put(pool) 167 | tz.Put(pool) 168 | v0.Put(pool) 169 | v1.Put(pool) 170 | v2.Put(pool) 171 | return e 172 | } 173 | 174 | func (e *gfP6) MulScalar(a *gfP6, b *GFp2, pool *bnPool) *gfP6 { 175 | e.x.Mul(a.x, b, pool) 176 | e.y.Mul(a.y, b, pool) 177 | e.z.Mul(a.z, b, pool) 178 | return e 179 | } 180 | 181 | func (e *gfP6) MulGFP(a *gfP6, b *big.Int) *gfP6 { 182 | e.x.MulScalar(a.x, b) 183 | e.y.MulScalar(a.y, b) 184 | e.z.MulScalar(a.z, b) 185 | return e 186 | } 187 | 188 | // MulTau computes τ·(aτ²+bτ+c) = bτ²+cτ+aξ 189 | func (e *gfP6) MulTau(a *gfP6, pool *bnPool) { 190 | tz := newGFp2(pool) 191 | tz.MulXi(a.x, pool) 192 | ty := newGFp2(pool) 193 | ty.Set(a.y) 194 | e.y.Set(a.z) 195 | e.x.Set(ty) 196 | e.z.Set(tz) 197 | tz.Put(pool) 198 | ty.Put(pool) 199 | } 200 | 201 | func (e *gfP6) Square(a *gfP6, pool *bnPool) *gfP6 { 202 | v0 := newGFp2(pool).Square(a.z, pool) 203 | v1 := newGFp2(pool).Square(a.y, pool) 204 | v2 := newGFp2(pool).Square(a.x, pool) 205 | 206 | c0 := newGFp2(pool).Add(a.x, a.y) 207 | c0.Square(c0, pool) 208 | c0.Sub(c0, v1) 209 | c0.Sub(c0, v2) 210 | c0.MulXi(c0, pool) 211 | c0.Add(c0, v0) 212 | 213 | c1 := newGFp2(pool).Add(a.y, a.z) 214 | c1.Square(c1, pool) 215 | c1.Sub(c1, v0) 216 | c1.Sub(c1, v1) 217 | xiV2 := newGFp2(pool).MulXi(v2, pool) 218 | c1.Add(c1, xiV2) 219 | 220 | c2 := newGFp2(pool).Add(a.x, a.z) 221 | c2.Square(c2, pool) 222 | c2.Sub(c2, v0) 223 | c2.Add(c2, v1) 224 | c2.Sub(c2, v2) 225 | 226 | e.x.Set(c2) 227 | e.y.Set(c1) 228 | e.z.Set(c0) 229 | 230 | v0.Put(pool) 231 | v1.Put(pool) 232 | v2.Put(pool) 233 | c0.Put(pool) 234 | c1.Put(pool) 235 | c2.Put(pool) 236 | xiV2.Put(pool) 237 | 238 | return e 239 | } 240 | 241 | func (e *gfP6) Invert(a *gfP6, pool *bnPool) *gfP6 { 242 | // See "Implementing cryptographic pairings", M. Scott, section 3.2. 243 | // ftp://136.206.11.249/pub/crypto/pairings.pdf 244 | 245 | // Here we can give a short explanation of how it works: let j be a cubic root of 246 | // unity in GF(p²) so that 1+j+j²=0. 247 | // Then (xτ² + yτ + z)(xj²τ² + yjτ + z)(xjτ² + yj²τ + z) 248 | // = (xτ² + yτ + z)(Cτ²+Bτ+A) 249 | // = (x³ξ²+y³ξ+z³-3ξxyz) = F is an element of the base field (the norm). 250 | // 251 | // On the other hand (xj²τ² + yjτ + z)(xjτ² + yj²τ + z) 252 | // = τ²(y²-ξxz) + τ(ξx²-yz) + (z²-ξxy) 253 | // 254 | // So that's why A = (z²-ξxy), B = (ξx²-yz), C = (y²-ξxz) 255 | t1 := newGFp2(pool) 256 | 257 | A := newGFp2(pool) 258 | A.Square(a.z, pool) 259 | t1.Mul(a.x, a.y, pool) 260 | t1.MulXi(t1, pool) 261 | A.Sub(A, t1) 262 | 263 | B := newGFp2(pool) 264 | B.Square(a.x, pool) 265 | B.MulXi(B, pool) 266 | t1.Mul(a.y, a.z, pool) 267 | B.Sub(B, t1) 268 | 269 | C := newGFp2(pool) 270 | C.Square(a.y, pool) 271 | t1.Mul(a.x, a.z, pool) 272 | C.Sub(C, t1) 273 | 274 | F := newGFp2(pool) 275 | F.Mul(C, a.y, pool) 276 | F.MulXi(F, pool) 277 | t1.Mul(A, a.z, pool) 278 | F.Add(F, t1) 279 | t1.Mul(B, a.x, pool) 280 | t1.MulXi(t1, pool) 281 | F.Add(F, t1) 282 | 283 | F.Invert(F, pool) 284 | 285 | e.x.Mul(C, F, pool) 286 | e.y.Mul(B, F, pool) 287 | e.z.Mul(A, F, pool) 288 | 289 | t1.Put(pool) 290 | A.Put(pool) 291 | B.Put(pool) 292 | C.Put(pool) 293 | F.Put(pool) 294 | 295 | return e 296 | } 297 | -------------------------------------------------------------------------------- /bn256ref/hash_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 David Lazar. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package bn256ref 6 | 7 | import ( 8 | "bytes" 9 | "crypto/rand" 10 | "math/big" 11 | "testing" 12 | ) 13 | 14 | func TestHashToCurvePoint(t *testing.T) { 15 | m := make([]byte, 32) 16 | for i := 0; i < 1000; i++ { 17 | rand.Read(m) 18 | point := hashToCurvePoint(m) 19 | if !point.IsOnCurve() { 20 | t.Errorf("hashToPoint(%q) is not on curve", m) 21 | } 22 | 23 | point2 := hashToCurvePoint(m) 24 | if point.x.Cmp(point2.x) != 0 || point.y.Cmp(point2.y) != 0 { 25 | t.Error("hashToPoint is non-deterministic!") 26 | } 27 | } 28 | } 29 | 30 | func TestHashToTwistSubgroup(t *testing.T) { 31 | pool := new(bnPool) 32 | m := make([]byte, 32) 33 | for i := 0; i < 200; i++ { 34 | rand.Read(m) 35 | point := hashToTwistSubgroup(m) 36 | 37 | pointAffine := newTwistPoint(pool) 38 | pointAffine.Set(point) 39 | pointAffine.MakeAffine(pool) 40 | if !pointAffine.IsOnCurve() { 41 | t.Fatalf("hashToPoint(%#v)=%s is not on curve", m, point) 42 | } 43 | 44 | point2 := hashToTwistSubgroup(m) 45 | if point.x.x.Cmp(point2.x.x) != 0 || point.x.y.Cmp(point2.x.y) != 0 { 46 | t.Fatalf("hashToPoint is non-deterministic!") 47 | } 48 | if point.y.x.Cmp(point2.y.x) != 0 || point.y.y.Cmp(point2.y.y) != 0 { 49 | t.Fatalf("hashToPoint is non-deterministic!") 50 | } 51 | 52 | po := newTwistPoint(pool).Mul(point, Order, pool) 53 | if !po.IsInfinity() { 54 | t.Fatalf("pt * Order is not infinity:\npt=%s\npt*O=%s", point, po) 55 | } 56 | } 57 | } 58 | 59 | func TestHashToTwistPoint(t *testing.T) { 60 | twistOrder := bigFromBase10("4225071460736223789158632931970842997974944076512730449869415062641653401945858362165497788692899734927503397351735636815753116967050122103770169737948493") 61 | 62 | pool := new(bnPool) 63 | m := make([]byte, 32) 64 | for i := 0; i < 200; i++ { 65 | rand.Read(m) 66 | point := hashToTwistPoint(m) 67 | 68 | pointAffine := newTwistPoint(pool) 69 | pointAffine.Set(point) 70 | pointAffine.MakeAffine(pool) 71 | if !pointAffine.IsOnCurve() { 72 | t.Fatalf("hashToPoint(%#v)=%s is not on curve", m, point) 73 | } 74 | 75 | po := newTwistPoint(pool).Mul(point, twistOrder, pool) 76 | if !po.IsInfinity() { 77 | t.Fatalf("pt * twistOrder is not infinity:\npt=%s\npt*O=%s", point, po) 78 | } 79 | } 80 | } 81 | 82 | // Confirm that elements of G2 are in the n-torsion subgroup. 83 | func TestRandomG2(t *testing.T) { 84 | pool := new(bnPool) 85 | for i := 0; i < 100; i++ { 86 | _, g2, _ := RandomG2(rand.Reader) 87 | po := newTwistPoint(pool).Mul(g2.p, Order, pool) 88 | if !po.IsInfinity() { 89 | t.Errorf("pt * Order is not infinity: %s", g2.p) 90 | } 91 | } 92 | } 93 | 94 | // Attempt to test lots of edge cases 95 | func mapGFp2(f func(a *GFp2)) { 96 | vvs := []int64{-23, -4, -3, -2, -1, 0, 1, 2, 3, 4, 23} 97 | vs := make([]*big.Int, len(vvs)) 98 | for i := range vs { 99 | vs[i] = big.NewInt(vvs[i]) 100 | } 101 | vs = append(vs, u, p, Order) 102 | 103 | a := &GFp2{new(big.Int), new(big.Int)} 104 | 105 | for _, x := range vs { 106 | for _, y := range vs { 107 | a.x.Set(x) 108 | a.y.Set(y) 109 | a.Minimal() 110 | f(a) 111 | } 112 | for i := 0; i < 20; i++ { 113 | r, _ := rand.Int(rand.Reader, p) 114 | a.x.Set(x) 115 | a.y.Set(r) 116 | a.Minimal() 117 | f(a) 118 | } 119 | } 120 | 121 | for _, y := range vs { 122 | for i := 0; i < 20; i++ { 123 | r, _ := rand.Int(rand.Reader, p) 124 | a.x.Set(r) 125 | a.y.Set(y) 126 | a.Minimal() 127 | f(a) 128 | } 129 | } 130 | 131 | for i := 0; i < 200; i++ { 132 | x, _ := rand.Int(rand.Reader, p) 133 | y, _ := rand.Int(rand.Reader, p) 134 | a.x.Set(x) 135 | a.y.Set(y) 136 | a.Minimal() 137 | f(a) 138 | } 139 | 140 | f(xiToPMinus1Over6) 141 | f(xiToPMinus1Over3) 142 | f(xiToPMinus1Over2) 143 | f(xiTo2PMinus2Over3) 144 | } 145 | 146 | func TestGFP2Sqrt(t *testing.T) { 147 | pool := new(bnPool) 148 | mapGFp2(func(a *GFp2) { 149 | r := newGFp2(pool).Sqrt(a) 150 | if r != nil { 151 | b := newGFp2(pool).Square(r, pool) 152 | if a.x.Cmp(b.x) != 0 || a.y.Cmp(b.y) != 0 { 153 | t.Errorf("bad: %s", a.String()) 154 | } 155 | } 156 | 157 | aa := newGFp2(pool).Square(a, pool) 158 | r = newGFp2(pool).Sqrt(aa) 159 | // TODO we can probably be more clever here 160 | if r == nil { 161 | t.Errorf("square root must exist for %s", aa) 162 | } 163 | }) 164 | } 165 | 166 | func TestExpConjugate(t *testing.T) { 167 | pool := new(bnPool) 168 | mapGFp2(func(a *GFp2) { 169 | e := newGFp2(pool).Exp(a, p, pool) 170 | c := newGFp2(pool).Conjugate(a) 171 | e.Minimal() 172 | c.Minimal() 173 | if e.x.Cmp(c.x) != 0 || e.y.Cmp(c.y) != 0 { 174 | t.Fatalf("false: a=%s\ne=%s\nc=%s", a.String(), e.String(), c.String()) 175 | } 176 | }) 177 | } 178 | 179 | func BenchmarkGFP2Sqrt(b *testing.B) { 180 | pool := new(bnPool) 181 | _, g2, _ := RandomG2(rand.Reader) 182 | x := g2.p.x 183 | y := newGFp2(pool) 184 | b.ResetTimer() 185 | for i := 0; i < b.N; i++ { 186 | y.Sqrt(x) 187 | } 188 | } 189 | 190 | func BenchmarkHashToG1(b *testing.B) { 191 | m := make([]byte, 32) 192 | rand.Read(m) 193 | g1 := new(G1) 194 | b.ResetTimer() 195 | for i := 0; i < b.N; i++ { 196 | g1.HashToPoint(m) 197 | } 198 | } 199 | 200 | func BenchmarkHashToG2(b *testing.B) { 201 | m := make([]byte, 32) 202 | rand.Read(m) 203 | g2 := new(G2) 204 | b.ResetTimer() 205 | for i := 0; i < b.N; i++ { 206 | g2.HashToPoint(m) 207 | } 208 | } 209 | 210 | func BenchmarkScalarBaseMultG1(b *testing.B) { 211 | r, _ := rand.Int(rand.Reader, Order) 212 | g1 := new(G1) 213 | b.ResetTimer() 214 | for i := 0; i < b.N; i++ { 215 | g1.ScalarBaseMult(r) 216 | } 217 | } 218 | 219 | func BenchmarkScalarMultG2(b *testing.B) { 220 | r, _ := rand.Int(rand.Reader, Order) 221 | _, x, _ := RandomG2(rand.Reader) 222 | g2 := new(G2) 223 | b.ResetTimer() 224 | for i := 0; i < b.N; i++ { 225 | g2.ScalarMult(x, r) 226 | } 227 | } 228 | 229 | // confirm g^k = g^(k mod Order) 230 | func TestScalarMultModOrderG2(t *testing.T) { 231 | _, g, _ := RandomG2(rand.Reader) 232 | for i := 0; i < 100; i++ { 233 | m := make([]byte, i) 234 | rand.Read(m) 235 | k := new(big.Int).SetBytes(m) 236 | kmod := new(big.Int).Mod(k, Order) 237 | 238 | gk := new(G2).ScalarMult(g, k) 239 | gkmod := new(G2).ScalarMult(g, kmod) 240 | 241 | if !bytes.Equal(gk.Marshal(), gkmod.Marshal()) { 242 | t.Fatalf("expect gk=gkmod: g=%s k=%s gk=%s gkmod=%s", g, k, gk, gkmod) 243 | } 244 | } 245 | } 246 | 247 | func TestMarshalInfinityG1(t *testing.T) { 248 | _, o, _ := RandomG1(rand.Reader) 249 | o.p.SetInfinity() 250 | bs := o.Marshal() 251 | oo, ok := new(G1).Unmarshal(bs) 252 | if !ok { 253 | t.Fatalf("Unmarshal failed") 254 | } 255 | if !o.p.IsInfinity() { 256 | t.Fatalf("no longer infinity") 257 | } 258 | if !oo.p.IsInfinity() { 259 | t.Fatalf("expected infinity") 260 | } 261 | } 262 | 263 | func TestMarshalInfinityG2(t *testing.T) { 264 | _, o, _ := RandomG2(rand.Reader) 265 | o.p.SetInfinity() 266 | bs := o.Marshal() 267 | oo, ok := new(G2).Unmarshal(bs) 268 | if !ok { 269 | t.Fatalf("Unmarshal failed") 270 | } 271 | if !o.p.IsInfinity() { 272 | t.Fatalf("no longer infinity") 273 | } 274 | if !oo.p.IsInfinity() { 275 | t.Fatalf("expected infinity") 276 | } 277 | } 278 | -------------------------------------------------------------------------------- /bn256/fp2e_triple2.s: -------------------------------------------------------------------------------- 1 | # File: dclxvi-20130329/fp2e_triple2.s 2 | # Author: Ruben Niederhagen, Peter Schwabe 3 | # Public Domain 4 | 5 | 6 | # qhasm: enter fp2e_triple2_qhasm 7 | .text 8 | .p2align 5 9 | .globl _fp2e_triple2_qhasm 10 | .globl fp2e_triple2_qhasm 11 | _fp2e_triple2_qhasm: 12 | fp2e_triple2_qhasm: 13 | push %rbp 14 | mov %rsp,%r11 15 | and $31,%r11 16 | add $0,%r11 17 | sub %r11,%rsp 18 | 19 | # qhasm: int64 rop 20 | 21 | # qhasm: input rop 22 | 23 | # qhasm: int6464 0r0 24 | 25 | # qhasm: int6464 0r1 26 | 27 | # qhasm: int6464 0r2 28 | 29 | # qhasm: int6464 0r3 30 | 31 | # qhasm: int6464 0r4 32 | 33 | # qhasm: int6464 0r5 34 | 35 | # qhasm: int6464 0r6 36 | 37 | # qhasm: int6464 0r7 38 | 39 | # qhasm: int6464 0r8 40 | 41 | # qhasm: int6464 0r9 42 | 43 | # qhasm: int6464 0r10 44 | 45 | # qhasm: int6464 0r11 46 | 47 | # qhasm: int6464 0t0 48 | 49 | # qhasm: int6464 0t1 50 | 51 | # qhasm: int6464 0t2 52 | 53 | # qhasm: int6464 0t3 54 | 55 | # qhasm: 0r0 = *(int128 *)(rop + 0) 56 | # asm 1: movdqa 0(0r0=int6464#1 57 | # asm 2: movdqa 0(0r0=%xmm0 58 | movdqa 0(%rdi),%xmm0 59 | 60 | # qhasm: 0r1 = *(int128 *)(rop + 16) 61 | # asm 1: movdqa 16(0r1=int6464#2 62 | # asm 2: movdqa 16(0r1=%xmm1 63 | movdqa 16(%rdi),%xmm1 64 | 65 | # qhasm: 0r2 = *(int128 *)(rop + 32) 66 | # asm 1: movdqa 32(0r2=int6464#3 67 | # asm 2: movdqa 32(0r2=%xmm2 68 | movdqa 32(%rdi),%xmm2 69 | 70 | # qhasm: 0r3 = *(int128 *)(rop + 48) 71 | # asm 1: movdqa 48(0r3=int6464#4 72 | # asm 2: movdqa 48(0r3=%xmm3 73 | movdqa 48(%rdi),%xmm3 74 | 75 | # qhasm: 0r4 = *(int128 *)(rop + 64) 76 | # asm 1: movdqa 64(0r4=int6464#5 77 | # asm 2: movdqa 64(0r4=%xmm4 78 | movdqa 64(%rdi),%xmm4 79 | 80 | # qhasm: 0r5 = *(int128 *)(rop + 80) 81 | # asm 1: movdqa 80(0r5=int6464#6 82 | # asm 2: movdqa 80(0r5=%xmm5 83 | movdqa 80(%rdi),%xmm5 84 | 85 | # qhasm: 0r6 = *(int128 *)(rop + 96) 86 | # asm 1: movdqa 96(0r6=int6464#7 87 | # asm 2: movdqa 96(0r6=%xmm6 88 | movdqa 96(%rdi),%xmm6 89 | 90 | # qhasm: 0r7 = *(int128 *)(rop + 112) 91 | # asm 1: movdqa 112(0r7=int6464#8 92 | # asm 2: movdqa 112(0r7=%xmm7 93 | movdqa 112(%rdi),%xmm7 94 | 95 | # qhasm: 0r8 = *(int128 *)(rop + 128) 96 | # asm 1: movdqa 128(0r8=int6464#9 97 | # asm 2: movdqa 128(0r8=%xmm8 98 | movdqa 128(%rdi),%xmm8 99 | 100 | # qhasm: 0r9 = *(int128 *)(rop + 144) 101 | # asm 1: movdqa 144(0r9=int6464#10 102 | # asm 2: movdqa 144(0r9=%xmm9 103 | movdqa 144(%rdi),%xmm9 104 | 105 | # qhasm: 0r10 = *(int128 *)(rop + 160) 106 | # asm 1: movdqa 160(0r10=int6464#11 107 | # asm 2: movdqa 160(0r10=%xmm10 108 | movdqa 160(%rdi),%xmm10 109 | 110 | # qhasm: 0r11 = *(int128 *)(rop + 176) 111 | # asm 1: movdqa 176(0r11=int6464#12 112 | # asm 2: movdqa 176(0r11=%xmm11 113 | movdqa 176(%rdi),%xmm11 114 | 115 | # qhasm: int6464 1t0 116 | 117 | # qhasm: 1t0 = THREE_THREE 118 | # asm 1: movdqa THREE_THREE,<1t0=int6464#13 119 | # asm 2: movdqa THREE_THREE,<1t0=%xmm12 120 | mov THREE_THREE@GOTPCREL(%rip), %rbp 121 | movdqa (%rbp),%xmm12 122 | 123 | # qhasm: float6464 0r0 *= 1t0 124 | # asm 1: mulpd <1t0=int6464#13,<0r0=int6464#1 125 | # asm 2: mulpd <1t0=%xmm12,<0r0=%xmm0 126 | mulpd %xmm12,%xmm0 127 | 128 | # qhasm: float6464 0r1 *= 1t0 129 | # asm 1: mulpd <1t0=int6464#13,<0r1=int6464#2 130 | # asm 2: mulpd <1t0=%xmm12,<0r1=%xmm1 131 | mulpd %xmm12,%xmm1 132 | 133 | # qhasm: float6464 0r2 *= 1t0 134 | # asm 1: mulpd <1t0=int6464#13,<0r2=int6464#3 135 | # asm 2: mulpd <1t0=%xmm12,<0r2=%xmm2 136 | mulpd %xmm12,%xmm2 137 | 138 | # qhasm: float6464 0r3 *= 1t0 139 | # asm 1: mulpd <1t0=int6464#13,<0r3=int6464#4 140 | # asm 2: mulpd <1t0=%xmm12,<0r3=%xmm3 141 | mulpd %xmm12,%xmm3 142 | 143 | # qhasm: float6464 0r4 *= 1t0 144 | # asm 1: mulpd <1t0=int6464#13,<0r4=int6464#5 145 | # asm 2: mulpd <1t0=%xmm12,<0r4=%xmm4 146 | mulpd %xmm12,%xmm4 147 | 148 | # qhasm: float6464 0r5 *= 1t0 149 | # asm 1: mulpd <1t0=int6464#13,<0r5=int6464#6 150 | # asm 2: mulpd <1t0=%xmm12,<0r5=%xmm5 151 | mulpd %xmm12,%xmm5 152 | 153 | # qhasm: float6464 0r6 *= 1t0 154 | # asm 1: mulpd <1t0=int6464#13,<0r6=int6464#7 155 | # asm 2: mulpd <1t0=%xmm12,<0r6=%xmm6 156 | mulpd %xmm12,%xmm6 157 | 158 | # qhasm: float6464 0r7 *= 1t0 159 | # asm 1: mulpd <1t0=int6464#13,<0r7=int6464#8 160 | # asm 2: mulpd <1t0=%xmm12,<0r7=%xmm7 161 | mulpd %xmm12,%xmm7 162 | 163 | # qhasm: float6464 0r8 *= 1t0 164 | # asm 1: mulpd <1t0=int6464#13,<0r8=int6464#9 165 | # asm 2: mulpd <1t0=%xmm12,<0r8=%xmm8 166 | mulpd %xmm12,%xmm8 167 | 168 | # qhasm: float6464 0r9 *= 1t0 169 | # asm 1: mulpd <1t0=int6464#13,<0r9=int6464#10 170 | # asm 2: mulpd <1t0=%xmm12,<0r9=%xmm9 171 | mulpd %xmm12,%xmm9 172 | 173 | # qhasm: float6464 0r10 *= 1t0 174 | # asm 1: mulpd <1t0=int6464#13,<0r10=int6464#11 175 | # asm 2: mulpd <1t0=%xmm12,<0r10=%xmm10 176 | mulpd %xmm12,%xmm10 177 | 178 | # qhasm: float6464 0r11 *= 1t0 179 | # asm 1: mulpd <1t0=int6464#13,<0r11=int6464#12 180 | # asm 2: mulpd <1t0=%xmm12,<0r11=%xmm11 181 | mulpd %xmm12,%xmm11 182 | 183 | # qhasm: *(int128 *)(rop + 0) = 0r0 184 | # asm 1: movdqa <0r0=int6464#1,0(0r0=int6464#1 57 | # asm 2: movdqa 0(<0rop=%rdi),>0r0=%xmm0 58 | movdqa 0(%rdi),%xmm0 59 | 60 | # qhasm: 0r1 = *(int128 *)(0rop + 16) 61 | # asm 1: movdqa 16(<0rop=int64#1),>0r1=int6464#2 62 | # asm 2: movdqa 16(<0rop=%rdi),>0r1=%xmm1 63 | movdqa 16(%rdi),%xmm1 64 | 65 | # qhasm: 0r2 = *(int128 *)(0rop + 32) 66 | # asm 1: movdqa 32(<0rop=int64#1),>0r2=int6464#3 67 | # asm 2: movdqa 32(<0rop=%rdi),>0r2=%xmm2 68 | movdqa 32(%rdi),%xmm2 69 | 70 | # qhasm: 0r3 = *(int128 *)(0rop + 48) 71 | # asm 1: movdqa 48(<0rop=int64#1),>0r3=int6464#4 72 | # asm 2: movdqa 48(<0rop=%rdi),>0r3=%xmm3 73 | movdqa 48(%rdi),%xmm3 74 | 75 | # qhasm: 0r4 = *(int128 *)(0rop + 64) 76 | # asm 1: movdqa 64(<0rop=int64#1),>0r4=int6464#5 77 | # asm 2: movdqa 64(<0rop=%rdi),>0r4=%xmm4 78 | movdqa 64(%rdi),%xmm4 79 | 80 | # qhasm: 0r5 = *(int128 *)(0rop + 80) 81 | # asm 1: movdqa 80(<0rop=int64#1),>0r5=int6464#6 82 | # asm 2: movdqa 80(<0rop=%rdi),>0r5=%xmm5 83 | movdqa 80(%rdi),%xmm5 84 | 85 | # qhasm: 0r6 = *(int128 *)(0rop + 96) 86 | # asm 1: movdqa 96(<0rop=int64#1),>0r6=int6464#7 87 | # asm 2: movdqa 96(<0rop=%rdi),>0r6=%xmm6 88 | movdqa 96(%rdi),%xmm6 89 | 90 | # qhasm: 0r7 = *(int128 *)(0rop + 112) 91 | # asm 1: movdqa 112(<0rop=int64#1),>0r7=int6464#8 92 | # asm 2: movdqa 112(<0rop=%rdi),>0r7=%xmm7 93 | movdqa 112(%rdi),%xmm7 94 | 95 | # qhasm: 0r8 = *(int128 *)(0rop + 128) 96 | # asm 1: movdqa 128(<0rop=int64#1),>0r8=int6464#9 97 | # asm 2: movdqa 128(<0rop=%rdi),>0r8=%xmm8 98 | movdqa 128(%rdi),%xmm8 99 | 100 | # qhasm: 0r9 = *(int128 *)(0rop + 144) 101 | # asm 1: movdqa 144(<0rop=int64#1),>0r9=int6464#10 102 | # asm 2: movdqa 144(<0rop=%rdi),>0r9=%xmm9 103 | movdqa 144(%rdi),%xmm9 104 | 105 | # qhasm: 0r10 = *(int128 *)(0rop + 160) 106 | # asm 1: movdqa 160(<0rop=int64#1),>0r10=int6464#11 107 | # asm 2: movdqa 160(<0rop=%rdi),>0r10=%xmm10 108 | movdqa 160(%rdi),%xmm10 109 | 110 | # qhasm: 0r11 = *(int128 *)(0rop + 176) 111 | # asm 1: movdqa 176(<0rop=int64#1),>0r11=int6464#12 112 | # asm 2: movdqa 176(<0rop=%rdi),>0r11=%xmm11 113 | movdqa 176(%rdi),%xmm11 114 | 115 | # qhasm: int6464 1t0 116 | 117 | # qhasm: 1t0 = MONE_MONE 118 | # asm 1: movdqa MONE_MONE,<1t0=int6464#13 119 | # asm 2: movdqa MONE_MONE,<1t0=%xmm12 120 | mov MONE_MONE@GOTPCREL(%rip), %rbp 121 | movdqa (%rbp),%xmm12 122 | 123 | # qhasm: float6464 0r0 *= 1t0 124 | # asm 1: mulpd <1t0=int6464#13,<0r0=int6464#1 125 | # asm 2: mulpd <1t0=%xmm12,<0r0=%xmm0 126 | mulpd %xmm12,%xmm0 127 | 128 | # qhasm: float6464 0r1 *= 1t0 129 | # asm 1: mulpd <1t0=int6464#13,<0r1=int6464#2 130 | # asm 2: mulpd <1t0=%xmm12,<0r1=%xmm1 131 | mulpd %xmm12,%xmm1 132 | 133 | # qhasm: float6464 0r2 *= 1t0 134 | # asm 1: mulpd <1t0=int6464#13,<0r2=int6464#3 135 | # asm 2: mulpd <1t0=%xmm12,<0r2=%xmm2 136 | mulpd %xmm12,%xmm2 137 | 138 | # qhasm: float6464 0r3 *= 1t0 139 | # asm 1: mulpd <1t0=int6464#13,<0r3=int6464#4 140 | # asm 2: mulpd <1t0=%xmm12,<0r3=%xmm3 141 | mulpd %xmm12,%xmm3 142 | 143 | # qhasm: float6464 0r4 *= 1t0 144 | # asm 1: mulpd <1t0=int6464#13,<0r4=int6464#5 145 | # asm 2: mulpd <1t0=%xmm12,<0r4=%xmm4 146 | mulpd %xmm12,%xmm4 147 | 148 | # qhasm: float6464 0r5 *= 1t0 149 | # asm 1: mulpd <1t0=int6464#13,<0r5=int6464#6 150 | # asm 2: mulpd <1t0=%xmm12,<0r5=%xmm5 151 | mulpd %xmm12,%xmm5 152 | 153 | # qhasm: float6464 0r6 *= 1t0 154 | # asm 1: mulpd <1t0=int6464#13,<0r6=int6464#7 155 | # asm 2: mulpd <1t0=%xmm12,<0r6=%xmm6 156 | mulpd %xmm12,%xmm6 157 | 158 | # qhasm: float6464 0r7 *= 1t0 159 | # asm 1: mulpd <1t0=int6464#13,<0r7=int6464#8 160 | # asm 2: mulpd <1t0=%xmm12,<0r7=%xmm7 161 | mulpd %xmm12,%xmm7 162 | 163 | # qhasm: float6464 0r8 *= 1t0 164 | # asm 1: mulpd <1t0=int6464#13,<0r8=int6464#9 165 | # asm 2: mulpd <1t0=%xmm12,<0r8=%xmm8 166 | mulpd %xmm12,%xmm8 167 | 168 | # qhasm: float6464 0r9 *= 1t0 169 | # asm 1: mulpd <1t0=int6464#13,<0r9=int6464#10 170 | # asm 2: mulpd <1t0=%xmm12,<0r9=%xmm9 171 | mulpd %xmm12,%xmm9 172 | 173 | # qhasm: float6464 0r10 *= 1t0 174 | # asm 1: mulpd <1t0=int6464#13,<0r10=int6464#11 175 | # asm 2: mulpd <1t0=%xmm12,<0r10=%xmm10 176 | mulpd %xmm12,%xmm10 177 | 178 | # qhasm: float6464 0r11 *= 1t0 179 | # asm 1: mulpd <1t0=int6464#13,<0r11=int6464#12 180 | # asm 2: mulpd <1t0=%xmm12,<0r11=%xmm11 181 | mulpd %xmm12,%xmm11 182 | 183 | # qhasm: *(int128 *)(0rop + 0) = 0r0 184 | # asm 1: movdqa <0r0=int6464#1,0(<0rop=int64#1) 185 | # asm 2: movdqa <0r0=%xmm0,0(<0rop=%rdi) 186 | movdqa %xmm0,0(%rdi) 187 | 188 | # qhasm: *(int128 *)(0rop + 16) = 0r1 189 | # asm 1: movdqa <0r1=int6464#2,16(<0rop=int64#1) 190 | # asm 2: movdqa <0r1=%xmm1,16(<0rop=%rdi) 191 | movdqa %xmm1,16(%rdi) 192 | 193 | # qhasm: *(int128 *)(0rop + 32) = 0r2 194 | # asm 1: movdqa <0r2=int6464#3,32(<0rop=int64#1) 195 | # asm 2: movdqa <0r2=%xmm2,32(<0rop=%rdi) 196 | movdqa %xmm2,32(%rdi) 197 | 198 | # qhasm: *(int128 *)(0rop + 48) = 0r3 199 | # asm 1: movdqa <0r3=int6464#4,48(<0rop=int64#1) 200 | # asm 2: movdqa <0r3=%xmm3,48(<0rop=%rdi) 201 | movdqa %xmm3,48(%rdi) 202 | 203 | # qhasm: *(int128 *)(0rop + 64) = 0r4 204 | # asm 1: movdqa <0r4=int6464#5,64(<0rop=int64#1) 205 | # asm 2: movdqa <0r4=%xmm4,64(<0rop=%rdi) 206 | movdqa %xmm4,64(%rdi) 207 | 208 | # qhasm: *(int128 *)(0rop + 80) = 0r5 209 | # asm 1: movdqa <0r5=int6464#6,80(<0rop=int64#1) 210 | # asm 2: movdqa <0r5=%xmm5,80(<0rop=%rdi) 211 | movdqa %xmm5,80(%rdi) 212 | 213 | # qhasm: *(int128 *)(0rop + 96) = 0r6 214 | # asm 1: movdqa <0r6=int6464#7,96(<0rop=int64#1) 215 | # asm 2: movdqa <0r6=%xmm6,96(<0rop=%rdi) 216 | movdqa %xmm6,96(%rdi) 217 | 218 | # qhasm: *(int128 *)(0rop + 112) = 0r7 219 | # asm 1: movdqa <0r7=int6464#8,112(<0rop=int64#1) 220 | # asm 2: movdqa <0r7=%xmm7,112(<0rop=%rdi) 221 | movdqa %xmm7,112(%rdi) 222 | 223 | # qhasm: *(int128 *)(0rop + 128) = 0r8 224 | # asm 1: movdqa <0r8=int6464#9,128(<0rop=int64#1) 225 | # asm 2: movdqa <0r8=%xmm8,128(<0rop=%rdi) 226 | movdqa %xmm8,128(%rdi) 227 | 228 | # qhasm: *(int128 *)(0rop + 144) = 0r9 229 | # asm 1: movdqa <0r9=int6464#10,144(<0rop=int64#1) 230 | # asm 2: movdqa <0r9=%xmm9,144(<0rop=%rdi) 231 | movdqa %xmm9,144(%rdi) 232 | 233 | # qhasm: *(int128 *)(0rop + 160) = 0r10 234 | # asm 1: movdqa <0r10=int6464#11,160(<0rop=int64#1) 235 | # asm 2: movdqa <0r10=%xmm10,160(<0rop=%rdi) 236 | movdqa %xmm10,160(%rdi) 237 | 238 | # qhasm: *(int128 *)(0rop + 176) = 0r11 239 | # asm 1: movdqa <0r11=int6464#12,176(<0rop=int64#1) 240 | # asm 2: movdqa <0r11=%xmm11,176(<0rop=%rdi) 241 | movdqa %xmm11,176(%rdi) 242 | 243 | # qhasm: leave 244 | add %r11,%rsp 245 | mov %rdi,%rax 246 | mov %rsi,%rdx 247 | pop %rbp 248 | ret 249 | -------------------------------------------------------------------------------- /bn256/fp2e_double2.s: -------------------------------------------------------------------------------- 1 | # File: dclxvi-20130329/fp2e_double2.s 2 | # Author: Ruben Niederhagen, Peter Schwabe 3 | # Public Domain 4 | 5 | 6 | # qhasm: enter fp2e_double2_qhasm 7 | .text 8 | .p2align 5 9 | .globl _fp2e_double2_qhasm 10 | .globl fp2e_double2_qhasm 11 | _fp2e_double2_qhasm: 12 | fp2e_double2_qhasm: 13 | push %rbp 14 | mov %rsp,%r11 15 | and $31,%r11 16 | add $0,%r11 17 | sub %r11,%rsp 18 | 19 | # qhasm: int64 0rop 20 | 21 | # qhasm: input 0rop 22 | 23 | # qhasm: int6464 0r0 24 | 25 | # qhasm: int6464 0r1 26 | 27 | # qhasm: int6464 0r2 28 | 29 | # qhasm: int6464 0r3 30 | 31 | # qhasm: int6464 0r4 32 | 33 | # qhasm: int6464 0r5 34 | 35 | # qhasm: int6464 0r6 36 | 37 | # qhasm: int6464 0r7 38 | 39 | # qhasm: int6464 0r8 40 | 41 | # qhasm: int6464 0r9 42 | 43 | # qhasm: int6464 0r10 44 | 45 | # qhasm: int6464 0r11 46 | 47 | # qhasm: int6464 0t0 48 | 49 | # qhasm: int6464 0t1 50 | 51 | # qhasm: int6464 0t2 52 | 53 | # qhasm: int6464 0t3 54 | 55 | # qhasm: 0r0 = *(int128 *)(0rop + 0) 56 | # asm 1: movdqa 0(<0rop=int64#1),>0r0=int6464#1 57 | # asm 2: movdqa 0(<0rop=%rdi),>0r0=%xmm0 58 | movdqa 0(%rdi),%xmm0 59 | 60 | # qhasm: 0r1 = *(int128 *)(0rop + 16) 61 | # asm 1: movdqa 16(<0rop=int64#1),>0r1=int6464#2 62 | # asm 2: movdqa 16(<0rop=%rdi),>0r1=%xmm1 63 | movdqa 16(%rdi),%xmm1 64 | 65 | # qhasm: 0r2 = *(int128 *)(0rop + 32) 66 | # asm 1: movdqa 32(<0rop=int64#1),>0r2=int6464#3 67 | # asm 2: movdqa 32(<0rop=%rdi),>0r2=%xmm2 68 | movdqa 32(%rdi),%xmm2 69 | 70 | # qhasm: 0r3 = *(int128 *)(0rop + 48) 71 | # asm 1: movdqa 48(<0rop=int64#1),>0r3=int6464#4 72 | # asm 2: movdqa 48(<0rop=%rdi),>0r3=%xmm3 73 | movdqa 48(%rdi),%xmm3 74 | 75 | # qhasm: 0r4 = *(int128 *)(0rop + 64) 76 | # asm 1: movdqa 64(<0rop=int64#1),>0r4=int6464#5 77 | # asm 2: movdqa 64(<0rop=%rdi),>0r4=%xmm4 78 | movdqa 64(%rdi),%xmm4 79 | 80 | # qhasm: 0r5 = *(int128 *)(0rop + 80) 81 | # asm 1: movdqa 80(<0rop=int64#1),>0r5=int6464#6 82 | # asm 2: movdqa 80(<0rop=%rdi),>0r5=%xmm5 83 | movdqa 80(%rdi),%xmm5 84 | 85 | # qhasm: 0r6 = *(int128 *)(0rop + 96) 86 | # asm 1: movdqa 96(<0rop=int64#1),>0r6=int6464#7 87 | # asm 2: movdqa 96(<0rop=%rdi),>0r6=%xmm6 88 | movdqa 96(%rdi),%xmm6 89 | 90 | # qhasm: 0r7 = *(int128 *)(0rop + 112) 91 | # asm 1: movdqa 112(<0rop=int64#1),>0r7=int6464#8 92 | # asm 2: movdqa 112(<0rop=%rdi),>0r7=%xmm7 93 | movdqa 112(%rdi),%xmm7 94 | 95 | # qhasm: 0r8 = *(int128 *)(0rop + 128) 96 | # asm 1: movdqa 128(<0rop=int64#1),>0r8=int6464#9 97 | # asm 2: movdqa 128(<0rop=%rdi),>0r8=%xmm8 98 | movdqa 128(%rdi),%xmm8 99 | 100 | # qhasm: 0r9 = *(int128 *)(0rop + 144) 101 | # asm 1: movdqa 144(<0rop=int64#1),>0r9=int6464#10 102 | # asm 2: movdqa 144(<0rop=%rdi),>0r9=%xmm9 103 | movdqa 144(%rdi),%xmm9 104 | 105 | # qhasm: 0r10 = *(int128 *)(0rop + 160) 106 | # asm 1: movdqa 160(<0rop=int64#1),>0r10=int6464#11 107 | # asm 2: movdqa 160(<0rop=%rdi),>0r10=%xmm10 108 | movdqa 160(%rdi),%xmm10 109 | 110 | # qhasm: 0r11 = *(int128 *)(0rop + 176) 111 | # asm 1: movdqa 176(<0rop=int64#1),>0r11=int6464#12 112 | # asm 2: movdqa 176(<0rop=%rdi),>0r11=%xmm11 113 | movdqa 176(%rdi),%xmm11 114 | 115 | # qhasm: int6464 1t0 116 | 117 | # qhasm: 1t0 = TWO_TWO 118 | # asm 1: movdqa TWO_TWO,<1t0=int6464#13 119 | # asm 2: movdqa TWO_TWO,<1t0=%xmm12 120 | mov TWO_TWO@GOTPCREL(%rip), %rbp 121 | movdqa (%rbp),%xmm12 122 | 123 | # qhasm: float6464 0r0 += 0r0 124 | # asm 1: addpd <0r0=int6464#1,<0r0=int6464#1 125 | # asm 2: addpd <0r0=%xmm0,<0r0=%xmm0 126 | addpd %xmm0,%xmm0 127 | 128 | # qhasm: float6464 0r1 *= 1t0 129 | # asm 1: mulpd <1t0=int6464#13,<0r1=int6464#2 130 | # asm 2: mulpd <1t0=%xmm12,<0r1=%xmm1 131 | mulpd %xmm12,%xmm1 132 | 133 | # qhasm: float6464 0r2 += 0r2 134 | # asm 1: addpd <0r2=int6464#3,<0r2=int6464#3 135 | # asm 2: addpd <0r2=%xmm2,<0r2=%xmm2 136 | addpd %xmm2,%xmm2 137 | 138 | # qhasm: float6464 0r3 *= 1t0 139 | # asm 1: mulpd <1t0=int6464#13,<0r3=int6464#4 140 | # asm 2: mulpd <1t0=%xmm12,<0r3=%xmm3 141 | mulpd %xmm12,%xmm3 142 | 143 | # qhasm: float6464 0r4 += 0r4 144 | # asm 1: addpd <0r4=int6464#5,<0r4=int6464#5 145 | # asm 2: addpd <0r4=%xmm4,<0r4=%xmm4 146 | addpd %xmm4,%xmm4 147 | 148 | # qhasm: float6464 0r5 *= 1t0 149 | # asm 1: mulpd <1t0=int6464#13,<0r5=int6464#6 150 | # asm 2: mulpd <1t0=%xmm12,<0r5=%xmm5 151 | mulpd %xmm12,%xmm5 152 | 153 | # qhasm: float6464 0r6 += 0r6 154 | # asm 1: addpd <0r6=int6464#7,<0r6=int6464#7 155 | # asm 2: addpd <0r6=%xmm6,<0r6=%xmm6 156 | addpd %xmm6,%xmm6 157 | 158 | # qhasm: float6464 0r7 *= 1t0 159 | # asm 1: mulpd <1t0=int6464#13,<0r7=int6464#8 160 | # asm 2: mulpd <1t0=%xmm12,<0r7=%xmm7 161 | mulpd %xmm12,%xmm7 162 | 163 | # qhasm: float6464 0r8 += 0r8 164 | # asm 1: addpd <0r8=int6464#9,<0r8=int6464#9 165 | # asm 2: addpd <0r8=%xmm8,<0r8=%xmm8 166 | addpd %xmm8,%xmm8 167 | 168 | # qhasm: float6464 0r9 *= 1t0 169 | # asm 1: mulpd <1t0=int6464#13,<0r9=int6464#10 170 | # asm 2: mulpd <1t0=%xmm12,<0r9=%xmm9 171 | mulpd %xmm12,%xmm9 172 | 173 | # qhasm: float6464 0r10 += 0r10 174 | # asm 1: addpd <0r10=int6464#11,<0r10=int6464#11 175 | # asm 2: addpd <0r10=%xmm10,<0r10=%xmm10 176 | addpd %xmm10,%xmm10 177 | 178 | # qhasm: float6464 0r11 *= 1t0 179 | # asm 1: mulpd <1t0=int6464#13,<0r11=int6464#12 180 | # asm 2: mulpd <1t0=%xmm12,<0r11=%xmm11 181 | mulpd %xmm12,%xmm11 182 | 183 | # qhasm: *(int128 *)(0rop + 0) = 0r0 184 | # asm 1: movdqa <0r0=int6464#1,0(<0rop=int64#1) 185 | # asm 2: movdqa <0r0=%xmm0,0(<0rop=%rdi) 186 | movdqa %xmm0,0(%rdi) 187 | 188 | # qhasm: *(int128 *)(0rop + 16) = 0r1 189 | # asm 1: movdqa <0r1=int6464#2,16(<0rop=int64#1) 190 | # asm 2: movdqa <0r1=%xmm1,16(<0rop=%rdi) 191 | movdqa %xmm1,16(%rdi) 192 | 193 | # qhasm: *(int128 *)(0rop + 32) = 0r2 194 | # asm 1: movdqa <0r2=int6464#3,32(<0rop=int64#1) 195 | # asm 2: movdqa <0r2=%xmm2,32(<0rop=%rdi) 196 | movdqa %xmm2,32(%rdi) 197 | 198 | # qhasm: *(int128 *)(0rop + 48) = 0r3 199 | # asm 1: movdqa <0r3=int6464#4,48(<0rop=int64#1) 200 | # asm 2: movdqa <0r3=%xmm3,48(<0rop=%rdi) 201 | movdqa %xmm3,48(%rdi) 202 | 203 | # qhasm: *(int128 *)(0rop + 64) = 0r4 204 | # asm 1: movdqa <0r4=int6464#5,64(<0rop=int64#1) 205 | # asm 2: movdqa <0r4=%xmm4,64(<0rop=%rdi) 206 | movdqa %xmm4,64(%rdi) 207 | 208 | # qhasm: *(int128 *)(0rop + 80) = 0r5 209 | # asm 1: movdqa <0r5=int6464#6,80(<0rop=int64#1) 210 | # asm 2: movdqa <0r5=%xmm5,80(<0rop=%rdi) 211 | movdqa %xmm5,80(%rdi) 212 | 213 | # qhasm: *(int128 *)(0rop + 96) = 0r6 214 | # asm 1: movdqa <0r6=int6464#7,96(<0rop=int64#1) 215 | # asm 2: movdqa <0r6=%xmm6,96(<0rop=%rdi) 216 | movdqa %xmm6,96(%rdi) 217 | 218 | # qhasm: *(int128 *)(0rop + 112) = 0r7 219 | # asm 1: movdqa <0r7=int6464#8,112(<0rop=int64#1) 220 | # asm 2: movdqa <0r7=%xmm7,112(<0rop=%rdi) 221 | movdqa %xmm7,112(%rdi) 222 | 223 | # qhasm: *(int128 *)(0rop + 128) = 0r8 224 | # asm 1: movdqa <0r8=int6464#9,128(<0rop=int64#1) 225 | # asm 2: movdqa <0r8=%xmm8,128(<0rop=%rdi) 226 | movdqa %xmm8,128(%rdi) 227 | 228 | # qhasm: *(int128 *)(0rop + 144) = 0r9 229 | # asm 1: movdqa <0r9=int6464#10,144(<0rop=int64#1) 230 | # asm 2: movdqa <0r9=%xmm9,144(<0rop=%rdi) 231 | movdqa %xmm9,144(%rdi) 232 | 233 | # qhasm: *(int128 *)(0rop + 160) = 0r10 234 | # asm 1: movdqa <0r10=int6464#11,160(<0rop=int64#1) 235 | # asm 2: movdqa <0r10=%xmm10,160(<0rop=%rdi) 236 | movdqa %xmm10,160(%rdi) 237 | 238 | # qhasm: *(int128 *)(0rop + 176) = 0r11 239 | # asm 1: movdqa <0r11=int6464#12,176(<0rop=int64#1) 240 | # asm 2: movdqa <0r11=%xmm11,176(<0rop=%rdi) 241 | movdqa %xmm11,176(%rdi) 242 | 243 | # qhasm: leave 244 | add %r11,%rsp 245 | mov %rdi,%rax 246 | mov %rsi,%rdx 247 | pop %rbp 248 | ret 249 | --------------------------------------------------------------------------------