├── .gitignore ├── README.md ├── dsa ├── algebraicMAC │ ├── README.md │ ├── assets │ │ └── macWBB.png │ ├── macWBB.go │ └── macWBB_test.go ├── bls │ ├── bls.go │ └── bls_test.go ├── ecdsa │ └── ecdsa.go ├── ed25519 │ ├── ed25519.go │ └── ed25519_test.go └── ringers17 │ ├── README.md │ ├── assets │ ├── sbABC1.png │ ├── sbABC2.png │ └── sig_ABC_1.png │ ├── ringers17.go │ └── ringers17_test.go ├── ecc ├── bls381 │ ├── bls381.go │ ├── e12.go │ ├── e2.go │ ├── e6.go │ ├── fp │ │ ├── arith.go │ │ └── element.go │ ├── fr │ │ ├── arith.go │ │ └── element.go │ ├── g1.go │ ├── g2.go │ └── pairing.go ├── bls381Utils │ ├── bls381Utils.go │ └── bls381Utils_test.go ├── bn256 │ ├── bn256.go │ ├── e12.go │ ├── e2.go │ ├── e6.go │ ├── fp │ │ ├── arith.go │ │ ├── element.go │ │ ├── element_mul.go │ │ ├── element_mul_amd64.go │ │ ├── element_mul_amd64.s │ │ ├── element_square.go │ │ ├── element_square_amd64.go │ │ ├── element_square_amd64.s │ │ └── element_test.go │ ├── fr │ │ ├── arith.go │ │ ├── element.go │ │ ├── element_mul.go │ │ ├── element_mul_amd64.go │ │ ├── element_mul_amd64.s │ │ ├── element_square.go │ │ ├── element_square_amd64.go │ │ ├── element_square_amd64.s │ │ └── element_test.go │ ├── g1.go │ ├── g2.go │ ├── pairing.go │ └── twistededwards │ │ ├── point.go │ │ ├── twistededwards.go │ │ └── twistededwards_test.go ├── bn256Utils │ └── bn256Utils.go ├── id.go ├── internal │ ├── debug │ │ ├── assert_debug.go │ │ └── assert_release.go │ ├── pool │ │ └── pool.go │ └── tests │ │ └── donotremove.txt ├── p256Utils │ └── p256Utils.go ├── pairingUtil.go ├── utils.go └── utils_test.go ├── encryption ├── ouEnc │ └── ouEnc.go ├── recrypt │ ├── README.md │ ├── assets │ │ ├── 1.png │ │ ├── 2.png │ │ ├── 3.png │ │ ├── 4.png │ │ ├── 5.png │ │ ├── 6.png │ │ └── 7.png │ ├── umbral.go │ └── umbral_test.go └── sherAes │ ├── README.md │ ├── aesGCM.go │ ├── aesGCM_test.go │ └── assets │ └── aes_gcm.png ├── go.mod ├── go.sum ├── main.go ├── proof ├── credentials │ ├── README.md │ ├── ringers17.go │ └── ringers17_test.go └── sigmaProtocol │ ├── README.md │ ├── assets │ └── NIZK.png │ ├── sigmaNIZK.go │ └── sigmaNIZK_test.go ├── shash └── merkleTree │ ├── merkleTree.go │ └── merkleTree_test.go ├── smath └── smath.go └── sutils ├── hashUtils.go └── utils.go /.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | */vendor 3 | /.idea -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # shercrypto 2 | 3 | The project is a crypto library written by [myself](https://www.sher.vip). This is a long-term task, and the project is still in its infancy. There is still much to be done. 4 | 5 | # Directory Structure 6 | 7 | ```sh 8 | ├─ecc # elliptic curves and its utils 9 | ├─encryptions # Encryption algorithms 10 | ├─math # wrapped math algorithms 11 | ├─signatures # Signature algorithms 12 | ├─utils # utils used in our project 13 | └─proof # zero-knowledge algorithms 14 | ``` 15 | 16 | # Curves 17 | 18 | - [x] P256(secp256k1) 19 | - [x] BN256 20 | - [ ] Curve25519(ed25519) 21 | - [x] BLS12-381 22 | 23 | # Algorithms 24 | 25 | ## Encryptions 26 | 27 | ### AES 28 | 29 | - [x] [AES_GCM](encryptions/sherAes) 30 | - [ ] AES_CBC 31 | - [ ] AES_OFB 32 | - [ ] ... 33 | 34 | ### Proxy Re-Encryption 35 | 36 | - [x] [Proxy Re-Encryption](encryptions/recrypt) 37 | - [ ] PRE based on pairing curves 38 | 39 | ### Signatures 40 | - [x] [Algebraic MAC](signatures/algebraicMAC) 41 | - [x] [Ringers17 Signature Scheme](signatures/ringers17) 42 | 43 | ### Proof 44 | - [x] [Schnorr NIZK](proof/schnorrNIZK) 45 | - [x] [An efficient self-blindable attribute-based credential scheme](proof/credentials) 46 | - [ ] Groth16 47 | - [ ] SuperSonic 48 | - [ ] Plonk 49 | - [ ] ... 50 | 51 | # API 52 | 53 | waiting... 54 | 55 | # Try Once 56 | 57 | ## main.go 58 | 59 | ```go 60 | package main 61 | 62 | import ( 63 | "shercrypto/encryptions/recrypt" 64 | "shercrypto/encryptions/sherAes" 65 | "shercrypto/proof/credentials" 66 | "shercrypto/proof/schnorrNIZK" 67 | "shercrypto/signatures/algebraicMAC" 68 | "shercrypto/signatures/ringers17" 69 | ) 70 | 71 | func main() { 72 | sherAes.TryOnce() 73 | schnorrNIZK.TryOnce() 74 | algebraicMAC.TryOnce() 75 | recrypt.TryOnce() 76 | ringers17.TryOnce() 77 | credentials.TryOnce() 78 | } 79 | 80 | ``` 81 | 82 | ## result 83 | 84 | ```go 85 | -----------AES GCM start------------- 86 | PlainText: Hello World 87 | CipherText: e50d7983b9cd370d81acdd6b8ead71ebce7c673360dbe414dda6d2 88 | Text after decryption: Hello World 89 | -----------AES GCM end------------- 90 | -----------Schnorr NIZK start------------- 91 | prove scheme: &{bn256.G1(2765277675911814263603122317192032835792128670690810428723533897562268041823, 49586042462698105485801742848540975459528495301419763370069561998058799158518) 101203739492224907737910371461811686326466639186416900782475394828361486058619 [52535026094174831019939789530503506497719844896198037700538454560875004523747] [bn256.G1(1, -2)] bn256.G1(31579067245623137095840985112895615236000784443397978551196743324484395357803, 8158011723950309062247001133324538857075303033263736761443546011274557459153) bn256.G1(31579067245623137095840985112895615236000784443397978551196743324484395357803, 8158011723950309062247001133324538857075303033263736761443546011274557459153)} 92 | Verify result: true 93 | -----------Schnorr NIZK end------------- 94 | -----------MacWBB start------------- 95 | sk size: 4 96 | sk: [46434447412861395819736421904033263516237479761643850028611036556916607781973 31506132741171721911329936666966367260718076823305152438443852298129490699462 60833970919623133354562418618154882467857170323141656224810009276976298209023 99564111793754186192721845214612516798695389966357248863028398800783234633419] 97 | pk size: 4 98 | pk: [0xc0000fd420 0xc0000fd4a0 0xc0000fd520 0xc0000fd5e0] 99 | mVec(i+5) 0 : 5 100 | mVec(i+5) 1 : 6 101 | mVec(i+5) 2 : 7 102 | mVec size: 3 103 | sigma 0 : [4 242 228 239 141 23 104 171 45 170 111 54 122 183 133 215 72 202 119 39 99 103 31 254 62 91 239 86 73 8 205 0 56 37 199 181 71 204 237 188 226 96 192 134 192 131 25 63 212 8 207 150 108 8 77 40 219 229 225 47 145 156 187 87 179] 104 | sigma 1 : [4 154 186 103 13 32 244 142 66 133 180 95 230 92 251 158 52 130 21 27 140 55 33 35 75 66 99 220 39 236 50 79 33 24 246 17 6 107 98 121 14 129 140 2 223 207 60 182 20 80 37 159 181 204 238 32 163 25 116 250 146 235 137 113 90] 105 | sigma 2 : [4 175 15 28 220 62 94 64 99 55 131 15 89 239 180 227 31 210 194 55 146 226 206 236 226 247 33 63 78 166 116 165 41 4 31 190 56 196 170 74 44 197 24 64 222 52 92 1 96 206 212 250 51 250 148 224 100 160 58 8 245 250 151 165 192] 106 | sigma 3 : [4 36 62 206 69 156 0 93 1 250 102 206 30 70 23 5 91 62 81 95 159 224 51 224 231 113 37 218 10 152 164 119 33 146 219 28 205 144 232 220 0 163 211 129 34 80 227 68 159 69 55 179 148 242 151 96 168 20 61 206 4 48 90 190 233] 107 | sigmas size: 4 108 | Verify result: true 109 | -----------MacWBB end------------- 110 | -----------Umbral Recrypt start------------- 111 | origin message: Hello, Proxy Re-Encryption 112 | Origin key: 0a5f914cd35fc0f3a863fed44741cf12f5e07d1ea3890dd2ef8d956c30cdaa2a 113 | capsule before encode: &{0xc0000690e0 0xc000069110 79834066787074872958791867706688064920113700865471069065778451396624296744082} 114 | capsule after decode: {0xc0001f2860 0xc0001f2be0 79834066787074872958791867706688064920113700865471069065778451396624296744082} 115 | ciphereText: b00eeb87d56c52a0536783e1602e049dac43781758a1732426b6b29f0d89f3e71f3d0ced707bc9f060bc 116 | recreate key: 0a5f914cd35fc0f3a863fed44741cf12f5e07d1ea3890dd2ef8d956c30cdaa2a 117 | rk: 98088047363772239475644965072235645236474817552355435145416873592609756598161 118 | PlainText by my own private key: Hello, Proxy Re-Encryption 119 | plainText: Hello, Proxy Re-Encryption 120 | -----------Umbral Recrypt end------------- 121 | -----------Ringers17 Signature Scheme start------------- 122 | sk size: 5 123 | pk: &{bn256.G2((49669264800538408924629494605233887214326801687935764735879957667131947959981,32054900377537653232131275454890688637482486680313138223544030988958904375296), (41734674735848283981714029716135946391370949387625834031191614747420650686289,51974789225479415249500903122590504624126230315561407938954994932881706836819), (51984352279513858737808192561089394103350601598048354176414560823659261769557,8017200616072249379437810264333163819164013753236904398735157687774339311464)) bn256.G2((10233073010022372351085344847949106796118912878754122692479376217382152415338,3602797831502366208092916118541218394579010910465082323519713221741856556460), (58232751234404998108140560217420006278440267338700832152413068897307834315166,3652612124163725116699085391901735539499912741744362962624560589623535541253), (56674162373692378226209391422442693411355480748770503854027207682894621321428,40275134195001228498556367826055210563829591400348910927115831526505380117043)) [bn256.G2((14236338516523640534116816167171654067808677418873595770858318870102074541674,55052808074860093551950472598120619919260166443885865591626844867385179353373), (16774226931214383101554919878736078547900447372506562865139989380893231620497,3346434753511654437077376040014598616344290518588478110712535690927878359352), (42179118109253703739931248597786598057686238434864971044594475724928958382911,40653407346437039177533553317531983911404599180171951873178247395087648194064)) bn256.G2((63036398243981829854102995697501924108762906431032636878993448325672042079773,54391768534608311875342058055627413056711550001459257004998120256543179555862), (47700944536478024334581356210744302778741901864910848599781770658301308990907,33069257628924823601913006354080259423808089201386525540032740171061106517282), (11147972747844451270031367565835682363626076820464923825233857514935555971254,39589261740700133319336166546572257056303775856879457682619530675895819287574)) bn256.G2((31647739413234688000866903555875201022600948643032053814794466061626731985839,60457650710843293892306808040676350067470559133590779412892790090726674031225), (15491938506942176840935321781174357109371561790052550290072021353602983983935,15338272597681298973667976519664905918213553452359018899495551268860857024308), (58904151459058264831741624243270838830743704923180898515528357989133663043887,56465095500374832268753057686616998420513757723627898359163402010104660180017))] 3 bn256.G2((37848951286614961562061345835589532580265876706740447710253817448755525833094,28797935870480322355967362122276807430559264643475381020460234498400290796544), (41869352989114254997845393872275704300480204789900503155350602766243927415487,19308359780309073298515029528974772626438681571134339480800832667258672430972), (39585619778816699581059127219442615210069715418865119674356537578182842443155,62913926741324377287247523499145308037257295177319161459389100700420950385733))} 124 | sigma: &{58256142834631314966713183908710409313004958501198606916659455254062118129691 bn256.G1(62816302012289028646862870677675658094590634740611790169824891815138990547320, 29167217514794659112428893875285672908401370843375531018508245682180683483606) bn256.G1(51252562952188836388754916350578549676635258853197568518005372677767352937557, 693540157506694639728266588332403333751490330400515925884014248554720366045) [bn256.G1(45565931530492188020803950403484670658603534446200651211288649633889614940531, 9842473872705609329619389560626107284161729747713055115803905626501062528243) bn256.G1(1666339485457583868929265545377367600861701289125138763210468595424834239852, 20582708465860430923762485426403569295027573263321022364271042853123013321984)] 2 bn256.G1(19482193552675954746843608244704246704471814941021154881822513663496416946247, 7784266883963503246062657229965073260666335543297655190968356010636629910385) bn256.G1(13885834342107253478676316236859503238680838483317683377044818868975705597438, 10034821273343775583017466787294662789251295337009105093572688547482210992573)} 125 | Verify result: true 126 | -----------Ringers17 Signature Scheme end------------- 127 | -----------Anonymous Credential start------------- 128 | Credential: &{[3 4 5] 0xc000382000} 129 | attr 0 : 3 130 | attr 1 : 4 131 | attr 2 : 5 132 | Verify origin credential: true 133 | SelectiveCredential: &{0xc0002986e0 0xc0003820a0} 134 | attr 0 : 3 135 | attr 1 : 4 136 | attr 2 : 104702657257102633579772822622124422673143939576486771274630765314225900831707 137 | Verify selective credential result: true 138 | -----------Anonymous Credential end------------- 139 | ``` 140 | 141 | 142 | 143 | Thanks! -------------------------------------------------------------------------------- /dsa/algebraicMAC/README.md: -------------------------------------------------------------------------------- 1 | # Algebraic MAC:$MAC_{wBB}$ 2 | 3 | ## Img 4 | 5 | ![macWBB](assets/macWBB.png) 6 | 7 | ## Origin 8 | 9 | $Setup(1^{\kappa})$: 10 | 11 | Output $par=(\mathbb{G},g,q) \xleftarrow{} GroupSetup(1^{\kappa})$ 12 | 13 | $KeyGen(par)$: 14 | 15 | Choose $x_i \xleftarrow{$} \mathbb{Z}_q^*$,where $i=(0,...,n)$,output secret keys: $sk=(x_0,...,x_n)$,output public parameters:$ipar \xleftarrow{} (X_0,...,X_n)$,where $X_i = g^{x_i}$ 16 | 17 | $MAC(sk,\vec{m})$: 18 | 19 | Make $sk=(x_0,...,x_n)$ and $\vec{m} = (m_1,...,m_n)$. Calculate signatures: and aux data:$\sigma_{x_i} \gets \sigma^{x_i}$. Output MAC Code:$(\sigma,\sigma_{x_1},...,\sigma_{x_n})$ 20 | 21 | $Verify(sk,\vec{m},\sigma)$: 22 | 23 | Output 1 iff $g=\sigma^{x_0 + \sum_{i=1}^{n} m_i x_i}$ 24 | 25 | # References 26 | 27 | Camenisch J, Drijvers M, Dzurenda P, et al. Fast keyed-verification anonymous credentials on standard smart cards[C]//IFIP International Conference on ICT Systems Security and Privacy Protection. Springer, Cham, 2019: 286-298. -------------------------------------------------------------------------------- /dsa/algebraicMAC/assets/macWBB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherLzp/scrypto/60ae416361d692ba2c7a57b8cccd87b1c30995f8/dsa/algebraicMAC/assets/macWBB.png -------------------------------------------------------------------------------- /dsa/algebraicMAC/macWBB.go: -------------------------------------------------------------------------------- 1 | package algebraicMAC 2 | 3 | import ( 4 | "crypto/ecdsa" 5 | "crypto/elliptic" 6 | "crypto/rand" 7 | "encoding/hex" 8 | "errors" 9 | "fmt" 10 | "math/big" 11 | "scrypto/ecc/p256Utils" 12 | "scrypto/smath" 13 | ) 14 | 15 | type macWBB struct { 16 | curve elliptic.Curve 17 | } 18 | 19 | func NewMacWBB(curve elliptic.Curve) (mac *macWBB) { 20 | return &macWBB{curve: curve} 21 | } 22 | 23 | type CurvePoint = ecdsa.PublicKey 24 | 25 | // macWBB.KeyGen algorithm 26 | // goal: generate n key pairs 27 | // sk = (x_0,...,x_n), x_i \gets_R Z_q 28 | // pk = ipar = (X_0,...,X_n), X_i = g^{x_i} 29 | func (this *macWBB) KeyGen(n int) (sk []*big.Int, pk []*CurvePoint, err error) { 30 | if n <= 0 { 31 | return nil, nil, errors.New("n should larger than 0") 32 | } 33 | // initialize sk,pk array 34 | for i := 0; i <= n; i++ { 35 | // our curve is P256 36 | // we use ecdsa to generate key pairs 37 | privateKey, err := ecdsa.GenerateKey(this.curve, rand.Reader) 38 | if err != nil { 39 | return nil, nil, err 40 | } 41 | publicKey := privateKey.PublicKey 42 | sk = append(sk, privateKey.D) 43 | pk = append(pk, &publicKey) 44 | } 45 | return sk, pk, nil 46 | } 47 | 48 | func (this *macWBB) Mac(sk []*big.Int, mVec []*big.Int) (sigmas []*CurvePoint, err error) { 49 | size := len(sk) 50 | if len(sk) <= 0 || len(mVec) <= 0 || len(sk) != len(mVec)+1 { 51 | return nil, errors.New("params size error") 52 | } 53 | // calculate sigma first 54 | // sigma = g^{1/(x_0 + \sum_{i=1}^{n} m_i x_i)} 55 | // prime number 56 | N := this.curve.Params().N 57 | sum := new(big.Int).SetInt64(0) 58 | for i, m := range mVec { 59 | mi_mul_xi := smath.Mul(m, sk[i+1], N) 60 | sum = smath.Add(sum, mi_mul_xi, N) 61 | } 62 | x0_add_sum := smath.Add(sk[0], sum, N) 63 | x0_add_sum_inverse := smath.ModInverse(x0_add_sum, N) 64 | // calculate sigma 65 | sigma := p256Utils.ScalarBaseMult(x0_add_sum_inverse) 66 | sigmas = append(sigmas, sigma) 67 | // sigma_i = sigma^{x_i} 68 | for i := 1; i < size; i++ { 69 | sigma_i := p256Utils.ScalarMult(sigma, sk[i]) 70 | sigmas = append(sigmas, sigma_i) 71 | } 72 | return sigmas, nil 73 | } 74 | 75 | func (this *macWBB) Verify(sk, mVec []*big.Int, sigma *CurvePoint) (res bool, err error) { 76 | if len(sk) <= 0 || len(mVec) <= 0 || len(sk) != len(mVec)+1 { 77 | return false, errors.New("params size error") 78 | } 79 | // get base generator: g 80 | g := p256Utils.ScalarBaseMult(new(big.Int).SetInt64(1)) 81 | // calculate vSigma = sigma^{x_0 + \sum+{i=1}^{n} m_i x_i} 82 | // prime number 83 | N := this.curve.Params().N 84 | sum := new(big.Int).SetInt64(0) 85 | for i, m := range mVec { 86 | mi_mul_xi := smath.Mul(m, sk[i+1], N) 87 | sum = smath.Add(sum, mi_mul_xi, N) 88 | } 89 | x0_add_sum := smath.Add(sk[0], sum, N) 90 | vSigma := p256Utils.ScalarMult(sigma, x0_add_sum) 91 | // check if g == vSigma 92 | gBytes := p256Utils.Marshal(g) 93 | vSigmaBytes := p256Utils.Marshal(vSigma) 94 | res = hex.EncodeToString(gBytes) == hex.EncodeToString(vSigmaBytes) 95 | return res, nil 96 | } 97 | 98 | func TryOnce() { 99 | fmt.Println("-----------MacWBB start-------------") 100 | p256 := elliptic.P256() 101 | mac := NewMacWBB(p256) 102 | sk, pk, err := mac.KeyGen(3) 103 | if err != nil { 104 | panic(err) 105 | } 106 | fmt.Println("sk size:", len(sk)) 107 | fmt.Println("sk:", sk) 108 | fmt.Println("pk size:", len(pk)) 109 | fmt.Println("pk:", pk) 110 | mVec := make([]*big.Int, 3) 111 | for i := 0; i < 3; i++ { 112 | mVec[i] = new(big.Int).SetInt64(int64(i + 5)) 113 | fmt.Println("mVec(i+5) ", i, ":", int64(i+5)) 114 | } 115 | fmt.Println("mVec size:", len(mVec)) 116 | sigmas, err := mac.Mac(sk, mVec) 117 | if err != nil { 118 | panic(err) 119 | } 120 | for i, sigma := range sigmas { 121 | fmt.Println("sigma ", i, ":", p256Utils.Marshal(sigma)) 122 | } 123 | fmt.Println("sigmas size:", len(sigmas)) 124 | res, err := mac.Verify(sk, mVec, sigmas[0]) 125 | if err != nil { 126 | panic(err) 127 | } 128 | fmt.Println("Verify result:", res) 129 | fmt.Println("-----------MacWBB end-------------") 130 | } 131 | -------------------------------------------------------------------------------- /dsa/algebraicMAC/macWBB_test.go: -------------------------------------------------------------------------------- 1 | package algebraicMAC 2 | 3 | import ( 4 | "crypto/elliptic" 5 | "fmt" 6 | "math/big" 7 | "testing" 8 | ) 9 | 10 | func TestMacWBB_KeyGen(t *testing.T) { 11 | p256 := elliptic.P256() 12 | mac := NewMacWBB(p256) 13 | sk, pk, err := mac.KeyGen(3) 14 | if err != nil { 15 | fmt.Println("Key gen error:", err) 16 | } 17 | fmt.Println("sk size:", len(sk)) 18 | fmt.Println("sk:", sk) 19 | fmt.Println("pk size:", len(pk)) 20 | fmt.Println("pk:", pk) 21 | } 22 | 23 | func TestMacWBB_Mac(t *testing.T) { 24 | p256 := elliptic.P256() 25 | mac := NewMacWBB(p256) 26 | sk, _, err := mac.KeyGen(3) 27 | if err != nil { 28 | fmt.Println("Key gen error:", err) 29 | } 30 | mVec := make([]*big.Int, 3) 31 | for i := 0; i < 3; i++ { 32 | mVec[i] = new(big.Int).SetInt64(int64(i + 2)) 33 | } 34 | sigmas, err := mac.Mac(sk, mVec) 35 | if err != nil { 36 | fmt.Println("Mac error:", err) 37 | } 38 | fmt.Println("sigmas size:", len(sigmas)) 39 | fmt.Println("sigmas:", sigmas) 40 | } 41 | 42 | func TestMacWBB_Verify(t *testing.T) { 43 | p256 := elliptic.P256() 44 | mac := NewMacWBB(p256) 45 | sk, _, err := mac.KeyGen(3) 46 | if err != nil { 47 | fmt.Println("Key gen error:", err) 48 | } 49 | mVec := make([]*big.Int, 3) 50 | for i := 0; i < 3; i++ { 51 | mVec[i] = new(big.Int).SetInt64(int64(i + 2)) 52 | } 53 | sigmas, err := mac.Mac(sk, mVec) 54 | sigma := sigmas[0] 55 | res, err := mac.Verify(sk, mVec, sigma) 56 | if err != nil { 57 | fmt.Println("Verify error:", err) 58 | } 59 | fmt.Println("Verify result:", res) 60 | } 61 | -------------------------------------------------------------------------------- /dsa/bls/bls.go: -------------------------------------------------------------------------------- 1 | package bls 2 | 3 | import ( 4 | "crypto/sha256" 5 | "math/big" 6 | "scrypto/ecc/bls381Utils" 7 | "scrypto/sutils" 8 | ) 9 | 10 | func GenerateKeyPair() (k *big.Int, K *bls381Utils.G2, err error) { 11 | // (sk,pk) = (k,K = g_2^{x}) 12 | return bls381Utils.RandomG2() 13 | } 14 | 15 | func G1Hash(message []byte) (h *bls381Utils.G1, err error) { 16 | mhash, err := sutils.GetHashValue(message, sha256.New) 17 | if err != nil { 18 | return nil, err 19 | } 20 | r := new(big.Int).SetBytes(mhash) 21 | h = bls381Utils.G1ScalarBaseMult(r) 22 | return h, nil 23 | } 24 | 25 | func Sign(k *big.Int, message []byte) (delta *bls381Utils.G1, err error) { 26 | // h = H(m) 27 | h, err := G1Hash(message) 28 | if err != nil { 29 | return nil, err 30 | } 31 | // \delta = h^{k} 32 | delta = bls381Utils.G1ScalarMult(h, k) 33 | return delta, nil 34 | } 35 | 36 | func Verify(K *bls381Utils.G2, message []byte, delta *bls381Utils.G1) bool { 37 | h, err := G1Hash(message) 38 | if err != nil { 39 | return false 40 | } 41 | // e(\delta, g_2) = e(h,K) 42 | p1 := bls381Utils.BLSPair(delta, &bls381Utils.BaseG2) 43 | p2 := bls381Utils.BLSPair(h, K) 44 | return p1.Equal(p2) 45 | } 46 | -------------------------------------------------------------------------------- /dsa/bls/bls_test.go: -------------------------------------------------------------------------------- 1 | package bls 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestTryOnce(t *testing.T) { 9 | k, K, err := GenerateKeyPair() 10 | if err != nil { 11 | panic(err) 12 | } 13 | m := []byte("hello") 14 | delta, err := Sign(k, m) 15 | if err != nil { 16 | panic(err) 17 | } 18 | res := Verify(K, m, delta) 19 | fmt.Println("res:", res) 20 | } 21 | -------------------------------------------------------------------------------- /dsa/ecdsa/ecdsa.go: -------------------------------------------------------------------------------- 1 | package ecdsaUtils 2 | 3 | import ( 4 | "bytes" 5 | "compress/gzip" 6 | "crypto/ecdsa" 7 | "crypto/elliptic" 8 | "crypto/rand" 9 | "crypto/x509" 10 | "encoding/hex" 11 | "math/big" 12 | "strings" 13 | ) 14 | 15 | type ecdsaCipher struct { 16 | curve elliptic.Curve 17 | } 18 | 19 | func NewECDSA(curve elliptic.Curve) (ecdsaSigner *ecdsaCipher) { 20 | ecdsaSigner = &ecdsaCipher{ 21 | curve: curve, 22 | } 23 | return ecdsaSigner 24 | } 25 | 26 | // Generate Private and Public key-pair 27 | func (*ecdsaCipher) GenerateKeys() (priKey *ecdsa.PrivateKey, pubKey *ecdsa.PublicKey, err error) { 28 | p256 := elliptic.P256() 29 | priKey, err = ecdsa.GenerateKey(p256, rand.Reader) 30 | if err != nil { 31 | return nil, nil, err 32 | } 33 | pubKey = &priKey.PublicKey 34 | return priKey, pubKey, nil 35 | } 36 | 37 | // ECDSA Sign 38 | func (*ecdsaCipher) Sign(privateKeyStr string, messageHash string) (string, error) { 39 | privateKeyBytes, err := hex.DecodeString(privateKeyStr) 40 | if err != nil { 41 | return "", err 42 | } 43 | privateKey, err := x509.ParseECPrivateKey(privateKeyBytes) 44 | if err != nil { 45 | return "", err 46 | } 47 | r, s, err := ecdsa.Sign(rand.Reader, privateKey, []byte(messageHash)) 48 | if err != nil { 49 | return "", err 50 | } 51 | rStr, _ := r.MarshalText() 52 | sStr, _ := s.MarshalText() 53 | var result bytes.Buffer 54 | w := gzip.NewWriter(&result) 55 | defer w.Close() 56 | _, err = w.Write([]byte(string(rStr) + "+" + string(sStr))) 57 | if err != nil { 58 | return "", err 59 | } 60 | w.Flush() 61 | return hex.EncodeToString(result.Bytes()), nil 62 | } 63 | 64 | // ECDSA Verify 65 | func (*ecdsaCipher) Verify(messageHash, signature string, publicKey string) (bool, error) { 66 | publicKeyBytes, err := hex.DecodeString(publicKey) 67 | if err != nil { 68 | return false, err 69 | } 70 | pubKey, _ := x509.ParsePKIXPublicKey(publicKeyBytes) 71 | sigBytes, err := hex.DecodeString(signature) 72 | if err != nil { 73 | return false, err 74 | } 75 | reader, err := gzip.NewReader(bytes.NewBuffer(sigBytes)) 76 | if err != nil { 77 | return false, err 78 | } 79 | defer reader.Close() 80 | buf := make([]byte, 1024) 81 | count, err := reader.Read(buf) 82 | if err != nil { 83 | return false, err 84 | } 85 | rsArr := strings.Split(string(buf[:count]), "+") 86 | if len(rsArr) != 2 { 87 | return false, err 88 | } 89 | var r, s big.Int 90 | err = r.UnmarshalText([]byte(rsArr[0])) 91 | if err != nil { 92 | return false, err 93 | } 94 | err = s.UnmarshalText([]byte(rsArr[1])) 95 | if err != nil { 96 | return false, err 97 | } 98 | result := ecdsa.Verify(pubKey.(*ecdsa.PublicKey), []byte(messageHash), &r, &s) 99 | return result, nil 100 | } 101 | -------------------------------------------------------------------------------- /dsa/ed25519/ed25519.go: -------------------------------------------------------------------------------- 1 | package ed25519 2 | 3 | import ( 4 | "crypto/rand" 5 | "golang.org/x/crypto/ed25519" 6 | ) 7 | 8 | func GenerateKeyPair() (pk *ed25519.PublicKey, sk *ed25519.PrivateKey, err error) { 9 | pkOri, skOri, err := ed25519.GenerateKey(rand.Reader) 10 | if err != nil { 11 | return nil, nil, err 12 | } 13 | return &pkOri, &skOri, nil 14 | } 15 | 16 | func Sign(sk *ed25519.PrivateKey, message []byte) []byte { 17 | signature := ed25519.Sign(*sk, message) 18 | return signature 19 | } 20 | 21 | func Verify(pk *ed25519.PublicKey, message []byte, signature []byte) bool { 22 | return ed25519.Verify(*pk, message, signature) 23 | } 24 | -------------------------------------------------------------------------------- /dsa/ed25519/ed25519_test.go: -------------------------------------------------------------------------------- 1 | package ed25519 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestTryOnce(t *testing.T) { 9 | pk, sk, _ := GenerateKeyPair() 10 | fmt.Println("pk:", pk) 11 | fmt.Println("sk:", sk) 12 | signature := Sign(sk, []byte("hello")) 13 | fmt.Println("sig:", signature) 14 | res := Verify(pk, []byte("hello"), signature) 15 | fmt.Println("res:", res) 16 | } 17 | 18 | func TestGenerateKeyPair(t *testing.T) { 19 | pk, sk, err := GenerateKeyPair() 20 | if err != nil { 21 | panic(err) 22 | } 23 | fmt.Println("sk:", sk) 24 | fmt.Println("pk:", pk) 25 | } 26 | 27 | func TestSign(t *testing.T) { 28 | _, sk, _ := GenerateKeyPair() 29 | signature := Sign(sk, []byte("hello")) 30 | fmt.Println("sig:", signature) 31 | } 32 | 33 | func TestVerify(t *testing.T) { 34 | pk, sk, _ := GenerateKeyPair() 35 | signature := Sign(sk, []byte("hello")) 36 | res := Verify(pk, []byte("hello"), signature) 37 | fmt.Println("res:", res) 38 | } 39 | -------------------------------------------------------------------------------- /dsa/ringers17/README.md: -------------------------------------------------------------------------------- 1 | # An efficient self-blindable attribute-based credential scheme 2 | 3 | ## Img 4 | 5 | ![sig_ABC_1](assets/sig_ABC_1.png) 6 | 7 | ## Origin 8 | 9 | ### Signature Scheme 10 | 11 | $KeyGen(1^{l },n)$: 12 | 13 | 发布者生成一个第三类型的配对曲线:$e : G_1 \times G_2 \rightarrow{} G_T$,满足$|p| = l$,其中$p$是曲线的阶。然后取值$Q \in_R G_2$,以及整数$a,a_0,...,a_n,z \in_R \mathbb{Z}_p^*$,然后令$A=Q^a,A_0 = Q^{a_0},A_n = Q^{a_n},Z=Q^z$。公钥是$\sigma=(p,e,Q,A,A_0,...,A_n,Z)$,私钥是$(a,a_0,...,a_n,z)$ 14 | 15 | $Sign(k_0,...,k_n)$: 16 | 17 | 发布者选择$\kappa \in_R \mathbb{Z}_p^*,K \in_R G_1$,令$S = K^a,S_0 = K^{a_0},...,S_n = K^{a_n},T=(K S^{\kappa} \prod_{i=0}^n S_i^{k_i})^z$,签名是:$(\kappa,K,S,S_0,...,S_n,T)$ 18 | 19 | $Verify((k_0,...,k_n),(\kappa,K,S,S_0,...,S_n,T),\sigma)$: 20 | 21 | 令$C = K S^{\kappa} \prod_{i=0}^n S_i^{k_i}$,验证$K,C \neq 1$,生成随机数$r,r_0,...,r_n \in_R \mathbb{Z}_p^*$,然后验证: 22 | $$ 23 | e(S^r \prod_{i=0}^n S_i^{r_i},Q) \overset{?}{=} e(K,A^r \prod_{i=0}^n A_i^{r_i}) \\ 24 | e(T,Q) \overset{?}{=} e(C,Z) 25 | $$ 26 | 27 | 28 | 其中$k_n \in \mathbb{Z}_p$是属性。 29 | 30 | # References 31 | 32 | Ringers S, Verheul E, Hoepman J H. An efficient self-blindable attribute-based credential scheme[C]//International Conference on Financial Cryptography and Data Security. Springer, Cham, 2017: 3-20. 33 | 34 | -------------------------------------------------------------------------------- /dsa/ringers17/assets/sbABC1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherLzp/scrypto/60ae416361d692ba2c7a57b8cccd87b1c30995f8/dsa/ringers17/assets/sbABC1.png -------------------------------------------------------------------------------- /dsa/ringers17/assets/sbABC2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherLzp/scrypto/60ae416361d692ba2c7a57b8cccd87b1c30995f8/dsa/ringers17/assets/sbABC2.png -------------------------------------------------------------------------------- /dsa/ringers17/assets/sig_ABC_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherLzp/scrypto/60ae416361d692ba2c7a57b8cccd87b1c30995f8/dsa/ringers17/assets/sig_ABC_1.png -------------------------------------------------------------------------------- /dsa/ringers17/ringers17_test.go: -------------------------------------------------------------------------------- 1 | package ringers17 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "math/big" 7 | "testing" 8 | ) 9 | 10 | func TestSigOfRingers_KeyGen(t *testing.T) { 11 | ringersSigner := NewSigOfRingers() 12 | sk, pk, err := ringersSigner.KeyGen(10) 13 | if err != nil { 14 | panic(err) 15 | } 16 | fmt.Println("sk:", sk) 17 | fmt.Println("pk:", pk) 18 | } 19 | 20 | func TestSigOfRingers_Sign(t *testing.T) { 21 | ringersSigner := NewSigOfRingers() 22 | sk, _, err := ringersSigner.KeyGen(2) 23 | if err != nil { 24 | panic(err) 25 | } 26 | var ks []*big.Int 27 | ks = append(ks, new(big.Int).SetUint64(100)) 28 | ks = append(ks, new(big.Int).SetUint64(200)) 29 | sigma, err := ringersSigner.Sign(ks, sk) 30 | if err != nil { 31 | panic(err) 32 | } 33 | sigmaBytes, err := json.Marshal(sigma) 34 | if err != nil { 35 | panic(err) 36 | } 37 | fmt.Println("sigma:", string(sigmaBytes)) 38 | } 39 | 40 | func TestSigOfRingers_ReRandomizeSignature(t *testing.T) { 41 | ringersSigner := NewSigOfRingers() 42 | sk, _, err := ringersSigner.KeyGen(2) 43 | if err != nil { 44 | panic(err) 45 | } 46 | var ks []*big.Int 47 | ks = append(ks, new(big.Int).SetUint64(100)) 48 | ks = append(ks, new(big.Int).SetUint64(200)) 49 | sigma, err := ringersSigner.Sign(ks, sk) 50 | if err != nil { 51 | panic(err) 52 | } 53 | beta, newSigma, err := ringersSigner.ReRandomizeSignature(sigma) 54 | if err != nil { 55 | panic(err) 56 | } 57 | fmt.Println("beta:", beta) 58 | newSigmaBytes, err := json.Marshal(newSigma) 59 | if err != nil { 60 | panic(err) 61 | } 62 | fmt.Println("new sigma:", string(newSigmaBytes)) 63 | } 64 | 65 | func TestSigOfRingers_Verify(t *testing.T) { 66 | ringersSigner := NewSigOfRingers() 67 | sk, pk, err := ringersSigner.KeyGen(2) 68 | if err != nil { 69 | panic(err) 70 | } 71 | var ks []*big.Int 72 | ks = append(ks, new(big.Int).SetUint64(100)) 73 | ks = append(ks, new(big.Int).SetUint64(200)) 74 | sigma, err := ringersSigner.Sign(ks, sk) 75 | if err != nil { 76 | panic(err) 77 | } 78 | res, err := ringersSigner.Verify(ks, sigma, pk) 79 | if err != nil { 80 | panic(err) 81 | } 82 | fmt.Println("verify result:", res) 83 | } 84 | 85 | func TestTryOnce(t *testing.T) { 86 | TryOnce() 87 | } 88 | -------------------------------------------------------------------------------- /ecc/bls381/bls381.go: -------------------------------------------------------------------------------- 1 | package bls381 2 | 3 | import ( 4 | "math/big" 5 | "sync" 6 | 7 | "scrypto/ecc" 8 | "scrypto/ecc/bls381/fp" 9 | ) 10 | 11 | // generate code for field tower, curve groups 12 | // add -testpoints to generate test points using sage 13 | // TODO g1_test.go, g2_test.go tests currently fail---just delete those files 14 | //go:generate go run ../internal/generator.go -out . -package bls381 -t 15132376222941642752 -tNeg -p 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787 -r 52435875175126190479447740508185965837690552500527637822603658699938581184513 -fp2 -1 -fp6 1,1 15 | 16 | // E: y**2=x**3+4 17 | // Etwist: y**2 = x**3+4*(u+1) 18 | 19 | var bls381 Curve 20 | var initOnce sync.Once 21 | 22 | // ID bls381 ID 23 | const ID = ecc.BLS381 24 | 25 | // parameters for pippenger ScalarMulByGen 26 | const sGen = 4 27 | const bGen = sGen 28 | 29 | type PairingResult = e12 30 | 31 | // BLS381 returns BLS381 curve 32 | func BLS381() *Curve { 33 | initOnce.Do(initBLS381) 34 | return &bls381 35 | } 36 | 37 | // Curve represents the BLS381 curve and pre-computed constants 38 | type Curve struct { 39 | B fp.Element // A, B coefficients of the curve x^3 = y^2 +AX+b 40 | 41 | G1Gen G1Jac // generator of torsion group G1Jac 42 | G2Gen G2Jac // generator of torsion group G2Jac 43 | 44 | g1Infinity G1Jac // infinity (in Jacobian coords) 45 | g2Infinity G2Jac 46 | 47 | // TODO store this number as a MAX_SIZE constant, or with build tags 48 | // NAF decomposition takes 65 trits for bls381 but only 64 trits for bls377 49 | loopCounter [65]int8 // NAF decomposition of t-1, t is the trace of the Frobenius 50 | 51 | // precomputed values for ScalarMulByGen 52 | tGenG1 [((1 << bGen) - 1)]G1Jac 53 | tGenG2 [((1 << bGen) - 1)]G2Jac 54 | } 55 | 56 | func initBLS381() { 57 | 58 | // A, B coeffs of the curve in Mont form 59 | bls381.B.SetUint64(4) 60 | 61 | // Setting G1Jac 62 | bls381.G1Gen.X.SetString("2407661716269791519325591009883849385849641130669941829988413640673772478386903154468379397813974815295049686961384") 63 | bls381.G1Gen.Y.SetString("821462058248938975967615814494474302717441302457255475448080663619194518120412959273482223614332657512049995916067") 64 | bls381.G1Gen.Z.SetString("1") 65 | 66 | // Setting G2Jac 67 | bls381.G2Gen.X.SetString("3914881020997020027725320596272602335133880006033342744016315347583472833929664105802124952724390025419912690116411", 68 | "277275454976865553761595788585036366131740173742845697399904006633521909118147462773311856983264184840438626176168") 69 | bls381.G2Gen.Y.SetString("253800087101532902362860387055050889666401414686580130872654083467859828854605749525591159464755920666929166876282", 70 | "1710145663789443622734372402738721070158916073226464929008132596760920130516982819361355832232719175024697380252309") 71 | bls381.G2Gen.Z.SetString("1", 72 | "0") 73 | 74 | // Setting the loop counter for Miller loop in NAF form 75 | // we can take |T|, see section C https://eprint.iacr.org/2008/096.pdf 76 | T, _ := new(big.Int).SetString("15132376222941642752", 10) 77 | ecc.NafDecomposition(T, bls381.loopCounter[:]) 78 | 79 | // infinity point G1 80 | bls381.g1Infinity.X.SetOne() 81 | bls381.g1Infinity.Y.SetOne() 82 | 83 | // infinity point G2 84 | bls381.g2Infinity.X.SetOne() 85 | bls381.g2Infinity.Y.SetOne() 86 | 87 | // precomputed values for ScalarMulByGen 88 | bls381.tGenG1[0].Set(&bls381.G1Gen) 89 | for j := 1; j < len(bls381.tGenG1)-1; j = j + 2 { 90 | bls381.tGenG1[j].Set(&bls381.tGenG1[j/2]).Double() 91 | bls381.tGenG1[j+1].Set(&bls381.tGenG1[(j+1)/2]).Add(&bls381, &bls381.tGenG1[j/2]) 92 | } 93 | bls381.tGenG2[0].Set(&bls381.G2Gen) 94 | for j := 1; j < len(bls381.tGenG2)-1; j = j + 2 { 95 | bls381.tGenG2[j].Set(&bls381.tGenG2[j/2]).Double() 96 | bls381.tGenG2[j+1].Set(&bls381.tGenG2[(j+1)/2]).Add(&bls381, &bls381.tGenG2[j/2]) 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /ecc/bls381/e2.go: -------------------------------------------------------------------------------- 1 | package bls381 2 | 3 | import ( 4 | "scrypto/ecc/bls381/fp" 5 | ) 6 | 7 | // e2 is a degree-two finite field extension of fp.Element: 8 | // A0 + A1u where u^2 == -1 is a quadratic nonresidue in fp 9 | 10 | type e2 struct { 11 | A0, A1 fp.Element 12 | } 13 | 14 | // SetString sets a e2 element from strings 15 | func (z *e2) SetString(s1, s2 string) *e2 { 16 | z.A0.SetString(s1) 17 | z.A1.SetString(s2) 18 | return z 19 | } 20 | 21 | func (z *e2) SetZero() *e2 { 22 | z.A0.SetZero() 23 | z.A1.SetZero() 24 | return z 25 | } 26 | 27 | // Clone returns a copy of self 28 | func (z *e2) Clone() *e2 { 29 | return &e2{ 30 | A0: z.A0, 31 | A1: z.A1, 32 | } 33 | } 34 | 35 | // Set sets an e2 from x 36 | func (z *e2) Set(x *e2) *e2 { 37 | z.A0.Set(&x.A0) 38 | z.A1.Set(&x.A1) 39 | return z 40 | } 41 | 42 | // Set sets z to 1 43 | func (z *e2) SetOne() *e2 { 44 | z.A0.SetOne() 45 | z.A1.SetZero() 46 | return z 47 | } 48 | 49 | // SetRandom sets a0 and a1 to random values 50 | func (z *e2) SetRandom() *e2 { 51 | z.A0.SetRandom() 52 | z.A1.SetRandom() 53 | return z 54 | } 55 | 56 | // Equal returns true if the two elements are equal, fasle otherwise 57 | func (z *e2) Equal(x *e2) bool { 58 | return z.A0.Equal(&x.A0) && z.A1.Equal(&x.A1) 59 | } 60 | 61 | // Equal returns true if the two elements are equal, fasle otherwise 62 | func (z *e2) IsZero() bool { 63 | return z.A0.IsZero() && z.A1.IsZero() 64 | } 65 | 66 | // Neg negates an e2 element 67 | func (z *e2) Neg(x *e2) *e2 { 68 | z.A0.Neg(&x.A0) 69 | z.A1.Neg(&x.A1) 70 | return z 71 | } 72 | 73 | // String implements Stringer eccInterface for fancy printing 74 | func (z *e2) String() string { 75 | return (z.A0.String() + "+" + z.A1.String() + "*u") 76 | } 77 | 78 | // ToMont converts to mont form 79 | func (z *e2) ToMont() *e2 { 80 | z.A0.ToMont() 81 | z.A1.ToMont() 82 | return z 83 | } 84 | 85 | // FromMont converts from mont form 86 | func (z *e2) FromMont() *e2 { 87 | z.A0.FromMont() 88 | z.A1.FromMont() 89 | return z 90 | } 91 | 92 | // Add adds two elements of e2 93 | func (z *e2) Add(x, y *e2) *e2 { 94 | z.A0.Add(&x.A0, &y.A0) 95 | z.A1.Add(&x.A1, &y.A1) 96 | return z 97 | } 98 | 99 | // AddAssign adds x to z 100 | func (z *e2) AddAssign(x *e2) *e2 { 101 | z.A0.AddAssign(&x.A0) 102 | z.A1.AddAssign(&x.A1) 103 | return z 104 | } 105 | 106 | // Sub two elements of e2 107 | func (z *e2) Sub(x, y *e2) *e2 { 108 | z.A0.Sub(&x.A0, &y.A0) 109 | z.A1.Sub(&x.A1, &y.A1) 110 | return z 111 | } 112 | 113 | // SubAssign subs x from z 114 | func (z *e2) SubAssign(x *e2) *e2 { 115 | z.A0.SubAssign(&x.A0) 116 | z.A1.SubAssign(&x.A1) 117 | return z 118 | } 119 | 120 | // Double doubles an e2 element 121 | func (z *e2) Double(x *e2) *e2 { 122 | z.A0.Double(&x.A0) 123 | z.A1.Double(&x.A1) 124 | return z 125 | } 126 | 127 | // Mul sets z to the e2-product of x,y, returns z 128 | func (z *e2) Mul(x, y *e2) *e2 { 129 | // (a+bu)*(c+du) == (ac+(-1)*bd) + (ad+bc)u where u^2 == -1 130 | // Karatsuba: 3 fp multiplications instead of 4 131 | // [1]: ac 132 | // [2]: bd 133 | // [3]: (a+b)*(c+d) 134 | // Then z.A0: [1] + (-1)*[2] 135 | // Then z.A1: [3] - [2] - [1] 136 | var ac, bd, cplusd, aplusbcplusd fp.Element 137 | 138 | ac.Mul(&x.A0, &y.A0) // [1]: ac 139 | bd.Mul(&x.A1, &y.A1) // [2]: bd 140 | cplusd.Add(&y.A0, &y.A1) // c+d 141 | aplusbcplusd.Add(&x.A0, &x.A1) // a+b 142 | aplusbcplusd.MulAssign(&cplusd) // [3]: (a+b)*(c+d) 143 | z.A1.Add(&ac, &bd) // ad+bc, [2] + [1] 144 | z.A1.Sub(&aplusbcplusd, &z.A1) // z.A1: [3] - [2] - [1] 145 | z.A0.Sub(&ac, &bd) // z.A0: [1] - [2] 146 | return z 147 | } 148 | 149 | // MulAssign sets z to the e2-product of z,x returns z 150 | func (z *e2) MulAssign(x *e2) *e2 { 151 | // (a+bu)*(c+du) == (ac+(-1)*bd) + (ad+bc)u where u^2 == -1 152 | // Karatsuba: 3 fp multiplications instead of 4 153 | // [1]: ac 154 | // [2]: bd 155 | // [3]: (a+b)*(c+d) 156 | // Then z.A0: [1] + (-1)*[2] 157 | // Then z.A1: [3] - [2] - [1] 158 | var ac, bd, cplusd, aplusbcplusd fp.Element 159 | 160 | ac.Mul(&z.A0, &x.A0) // [1]: ac 161 | bd.Mul(&z.A1, &x.A1) // [2]: bd 162 | cplusd.Add(&x.A0, &x.A1) // c+d 163 | aplusbcplusd.Add(&z.A0, &z.A1) // a+b 164 | aplusbcplusd.MulAssign(&cplusd) // [3]: (a+b)*(c+d) 165 | z.A1.Add(&ac, &bd) // ad+bc, [2] + [1] 166 | z.A1.Sub(&aplusbcplusd, &z.A1) // z.A1: [3] - [2] - [1] 167 | z.A0.Sub(&ac, &bd) // z.A0: [1] - [2] 168 | return z 169 | } 170 | 171 | // Square sets z to the e2-product of x,x returns z 172 | func (z *e2) Square(x *e2) *e2 { 173 | // (a+bu)^2 == (a^2+(-1)*b^2) + (2ab)u where u^2 == -1 174 | // Complex method: 2 fp multiplications instead of 3 175 | // [1]: ab 176 | // [2]: (a+b)*(a+(-1)*b) 177 | // Then z.A0: [2] - (-1+1)*[1] 178 | // Then z.A1: 2[1] 179 | // optimize for quadratic nonresidue -1 180 | var aplusb fp.Element 181 | var result e2 182 | 183 | aplusb.Add(&x.A0, &x.A1) // a+b 184 | result.A0.Sub(&x.A0, &x.A1) // a-b 185 | result.A0.MulAssign(&aplusb) // [2]: (a+b)*(a-b) 186 | result.A1.Mul(&x.A0, &x.A1).Double(&result.A1) // [1]: ab 187 | 188 | z.Set(&result) 189 | 190 | return z 191 | } 192 | 193 | // MulByNonSquare multiplies an element by (0,1) 194 | // TODO deprecate in favor of inlined MulByNonResidue in fp6 package 195 | func (z *e2) MulByNonSquare(x *e2) *e2 { 196 | a := x.A0 197 | MulByNonResidue(&z.A0, &x.A1) 198 | z.A1 = a 199 | return z 200 | } 201 | 202 | // Inverse sets z to the e2-inverse of x, returns z 203 | func (z *e2) Inverse(x *e2) *e2 { 204 | // Algorithm 8 from https://eprint.iacr.org/2010/354.pdf 205 | var a0, a1, t0, t1 fp.Element 206 | 207 | a0 = x.A0 // = is slightly faster than Set() 208 | a1 = x.A1 // = is slightly faster than Set() 209 | 210 | t0.Square(&a0) // step 1 211 | t1.Square(&a1) // step 2 212 | t0.Add(&t0, &t1) // step 3 213 | t1.Inverse(&t0) // step 4 214 | z.A0.Mul(&a0, &t1) // step 5 215 | z.A1.Neg(&a1).MulAssign(&t1) // step 6 216 | 217 | return z 218 | } 219 | 220 | // MulByElement multiplies an element in e2 by an element in fp 221 | func (z *e2) MulByElement(x *e2, y *fp.Element) *e2 { 222 | var yCopy fp.Element 223 | yCopy.Set(y) 224 | z.A0.Mul(&x.A0, &yCopy) 225 | z.A1.Mul(&x.A1, &yCopy) 226 | return z 227 | } 228 | 229 | // Conjugate conjugates an element in e2 230 | func (z *e2) Conjugate(x *e2) *e2 { 231 | z.A0.Set(&x.A0) 232 | z.A1.Neg(&x.A1) 233 | return z 234 | } 235 | 236 | // MulByNonResidue multiplies a fp.Element by -1 237 | // It would be nice to make this a method of fp.Element but fp.Element is outside this package 238 | func MulByNonResidue(out, in *fp.Element) *fp.Element { 239 | (out).Neg(in) 240 | return out 241 | } 242 | 243 | // MulByNonResidueInv multiplies a fp.Element by -1^{-1} 244 | // It would be nice to make this a method of fp.Element but fp.Element is outside this package 245 | func MulByNonResidueInv(out, in *fp.Element) *fp.Element { 246 | // TODO this should be a no-op when out==in 247 | (out).Set(in) 248 | return out 249 | } 250 | -------------------------------------------------------------------------------- /ecc/bls381/e6.go: -------------------------------------------------------------------------------- 1 | package bls381 2 | 3 | import "scrypto/ecc/bls381/fp" 4 | 5 | // e6 is a degree-three finite field extension of fp2: 6 | // B0 + B1v + B2v^2 where v^3-1,1 is irrep in fp2 7 | 8 | type e6 struct { 9 | B0, B1, B2 e2 10 | } 11 | 12 | // SetString sets a e6 elmt from stringf 13 | func (z *e6) SetString(s1, s2, s3, s4, s5, s6 string) *e6 { 14 | z.B0.SetString(s1, s2) 15 | z.B1.SetString(s3, s4) 16 | z.B2.SetString(s5, s6) 17 | return z 18 | } 19 | 20 | // Set Sets a e6 elmt form another e6 elmt 21 | func (z *e6) Set(x *e6) *e6 { 22 | z.B0 = x.B0 23 | z.B1 = x.B1 24 | z.B2 = x.B2 25 | return z 26 | } 27 | 28 | // Equal compares two elements in e6 29 | func (z *e6) Equal(x *e6) bool { 30 | return z.B0.Equal(&x.B0) && z.B1.Equal(&x.B1) && z.B2.Equal(&x.B2) 31 | } 32 | 33 | // ToMont converts to Mont form 34 | func (z *e6) ToMont() *e6 { 35 | z.B0.ToMont() 36 | z.B1.ToMont() 37 | z.B2.ToMont() 38 | return z 39 | } 40 | 41 | // FromMont converts from Mont form 42 | func (z *e6) FromMont() *e6 { 43 | z.B0.FromMont() 44 | z.B1.FromMont() 45 | z.B2.FromMont() 46 | return z 47 | } 48 | 49 | // Add adds two elements of e6 50 | func (z *e6) Add(x, y *e6) *e6 { 51 | z.B0.Add(&x.B0, &y.B0) 52 | z.B1.Add(&x.B1, &y.B1) 53 | z.B2.Add(&x.B2, &y.B2) 54 | return z 55 | } 56 | 57 | // Neg negates the e6 number 58 | func (z *e6) Neg(x *e6) *e6 { 59 | z.B0.Neg(&z.B0) 60 | z.B1.Neg(&z.B1) 61 | z.B2.Neg(&z.B2) 62 | return z 63 | } 64 | 65 | // Sub two elements of e6 66 | func (z *e6) Sub(x, y *e6) *e6 { 67 | z.B0.Sub(&x.B0, &y.B0) 68 | z.B1.Sub(&x.B1, &y.B1) 69 | z.B2.Sub(&x.B2, &y.B2) 70 | return z 71 | } 72 | 73 | // MulByGen Multiplies by v, root of X^3-1,1 74 | // TODO deprecate in favor of inlined MulByNonResidue in fp12 package 75 | func (z *e6) MulByGen(x *e6) *e6 { 76 | var result e6 77 | 78 | result.B1 = x.B0 79 | result.B2 = x.B1 80 | { // begin: inline result.B0.MulByNonResidue(&x.B2) 81 | var buf e2 82 | buf.Set(&x.B2) 83 | result.B0.A1.Add(&buf.A0, &buf.A1) 84 | { // begin: inline MulByNonResidue(&(result.B0).A0, &buf.A1) 85 | (&(result.B0).A0).Neg(&buf.A1) 86 | } // end: inline MulByNonResidue(&(result.B0).A0, &buf.A1) 87 | result.B0.A0.AddAssign(&buf.A0) 88 | } // end: inline result.B0.MulByNonResidue(&x.B2) 89 | 90 | z.Set(&result) 91 | return z 92 | } 93 | 94 | // Double doubles an element in e6 95 | func (z *e6) Double(x *e6) *e6 { 96 | z.B0.Double(&x.B0) 97 | z.B1.Double(&x.B1) 98 | z.B2.Double(&x.B2) 99 | return z 100 | } 101 | 102 | // String puts e6 elmt in string form 103 | func (z *e6) String() string { 104 | return (z.B0.String() + "+(" + z.B1.String() + ")*v+(" + z.B2.String() + ")*v**2") 105 | } 106 | 107 | // Mul multiplies two numbers in e6 108 | func (z *e6) Mul(x, y *e6) *e6 { 109 | // Algorithm 13 from https://eprint.iacr.org/2010/354.pdf 110 | var rb0, b0, b1, b2, b3, b4 e2 111 | 112 | b0.Mul(&x.B0, &y.B0) // step 1 113 | b1.Mul(&x.B1, &y.B1) // step 2 114 | b2.Mul(&x.B2, &y.B2) // step 3 115 | 116 | // step 4 117 | b3.Add(&x.B1, &x.B2) 118 | b4.Add(&y.B1, &y.B2) 119 | rb0.Mul(&b3, &b4). 120 | SubAssign(&b1). 121 | SubAssign(&b2) 122 | { // begin: inline rb0.MulByNonResidue(&rb0) 123 | var buf e2 124 | buf.Set(&rb0) 125 | rb0.A1.Add(&buf.A0, &buf.A1) 126 | { // begin: inline MulByNonResidue(&(rb0).A0, &buf.A1) 127 | (&(rb0).A0).Neg(&buf.A1) 128 | } // end: inline MulByNonResidue(&(rb0).A0, &buf.A1) 129 | rb0.A0.AddAssign(&buf.A0) 130 | } // end: inline rb0.MulByNonResidue(&rb0) 131 | rb0.AddAssign(&b0) 132 | 133 | // step 5 134 | b3.Add(&x.B0, &x.B1) 135 | b4.Add(&y.B0, &y.B1) 136 | z.B1.Mul(&b3, &b4). 137 | SubAssign(&b0). 138 | SubAssign(&b1) 139 | { // begin: inline b3.MulByNonResidue(&b2) 140 | var buf e2 141 | buf.Set(&b2) 142 | b3.A1.Add(&buf.A0, &buf.A1) 143 | { // begin: inline MulByNonResidue(&(b3).A0, &buf.A1) 144 | (&(b3).A0).Neg(&buf.A1) 145 | } // end: inline MulByNonResidue(&(b3).A0, &buf.A1) 146 | b3.A0.AddAssign(&buf.A0) 147 | } // end: inline b3.MulByNonResidue(&b2) 148 | z.B1.AddAssign(&b3) 149 | 150 | // step 6 151 | b3.Add(&x.B0, &x.B2) 152 | b4.Add(&y.B0, &y.B2) 153 | z.B2.Mul(&b3, &b4). 154 | SubAssign(&b0). 155 | SubAssign(&b2). 156 | AddAssign(&b1) 157 | 158 | z.B0 = rb0 159 | return z 160 | } 161 | 162 | // MulByE2 multiplies x by an elements of e2 163 | func (z *e6) MulByE2(x *e6, y *e2) *e6 { 164 | var yCopy e2 165 | yCopy.Set(y) 166 | z.B0.Mul(&x.B0, &yCopy) 167 | z.B1.Mul(&x.B1, &yCopy) 168 | z.B2.Mul(&x.B2, &yCopy) 169 | return z 170 | } 171 | 172 | // MulByNotv2 multiplies x by y with &y.b2=0 173 | func (z *e6) MulByNotv2(x, y *e6) *e6 { 174 | // Algorithm 15 from https://eprint.iacr.org/2010/354.pdf 175 | var rb0, b0, b1, b2, b3 e2 176 | 177 | b0.Mul(&x.B0, &y.B0) // step 1 178 | b1.Mul(&x.B1, &y.B1) // step 2 179 | 180 | // step 3 181 | b2.Add(&x.B1, &x.B2) 182 | rb0.Mul(&b2, &y.B1). 183 | SubAssign(&b1) 184 | { // begin: inline rb0.MulByNonResidue(&rb0) 185 | var buf e2 186 | buf.Set(&rb0) 187 | rb0.A1.Add(&buf.A0, &buf.A1) 188 | { // begin: inline MulByNonResidue(&(rb0).A0, &buf.A1) 189 | (&(rb0).A0).Neg(&buf.A1) 190 | } // end: inline MulByNonResidue(&(rb0).A0, &buf.A1) 191 | rb0.A0.AddAssign(&buf.A0) 192 | } // end: inline rb0.MulByNonResidue(&rb0) 193 | rb0.AddAssign(&b0) 194 | 195 | // step 4 196 | b2.Add(&x.B0, &x.B1) 197 | b3.Add(&y.B0, &y.B1) 198 | z.B1.Mul(&b2, &b3). 199 | SubAssign(&b0). 200 | SubAssign(&b1) 201 | 202 | // step 5 203 | z.B2.Mul(&x.B2, &y.B0). 204 | AddAssign(&b1) 205 | 206 | z.B0 = rb0 207 | return z 208 | } 209 | 210 | // Square squares a e6 211 | func (z *e6) Square(x *e6) *e6 { 212 | // Algorithm 16 from https://eprint.iacr.org/2010/354.pdf 213 | var b0, b1, b2, b3, b4 e2 214 | 215 | b3.Mul(&x.B0, &x.B1).Double(&b3) // step 1 216 | b4.Square(&x.B2) // step 2 217 | 218 | // step 3 219 | { // begin: inline b0.MulByNonResidue(&b4) 220 | var buf e2 221 | buf.Set(&b4) 222 | b0.A1.Add(&buf.A0, &buf.A1) 223 | { // begin: inline MulByNonResidue(&(b0).A0, &buf.A1) 224 | (&(b0).A0).Neg(&buf.A1) 225 | } // end: inline MulByNonResidue(&(b0).A0, &buf.A1) 226 | b0.A0.AddAssign(&buf.A0) 227 | } // end: inline b0.MulByNonResidue(&b4) 228 | b0.AddAssign(&b3) 229 | 230 | b1.Sub(&b3, &b4) // step 4 231 | b2.Square(&x.B0) // step 5 232 | b3.Sub(&x.B0, &x.B1).AddAssign(&x.B2).Square(&b3) // steps 6 and 8 233 | b4.Mul(&x.B1, &x.B2).Double(&b4) // step 7 234 | 235 | // step 9 236 | { // begin: inline z.B0.MulByNonResidue(&b4) 237 | var buf e2 238 | buf.Set(&b4) 239 | z.B0.A1.Add(&buf.A0, &buf.A1) 240 | { // begin: inline MulByNonResidue(&(z.B0).A0, &buf.A1) 241 | (&(z.B0).A0).Neg(&buf.A1) 242 | } // end: inline MulByNonResidue(&(z.B0).A0, &buf.A1) 243 | z.B0.A0.AddAssign(&buf.A0) 244 | } // end: inline z.B0.MulByNonResidue(&b4) 245 | z.B0.AddAssign(&b2) 246 | 247 | // step 10 248 | z.B2.Add(&b1, &b3). 249 | AddAssign(&b4). 250 | SubAssign(&b2) 251 | 252 | z.B1 = b0 253 | return z 254 | } 255 | 256 | // Square2 squares a e6 257 | func (z *e6) Square2(x *e6) *e6 { 258 | // Karatsuba from Section 4 of https://eprint.iacr.org/2006/471.pdf 259 | var v0, v1, v2, v01, v02, v12 e2 260 | v0.Square(&x.B0) 261 | v1.Square(&x.B1) 262 | v2.Square(&x.B2) 263 | v01.Add(&x.B0, &x.B1) 264 | v01.Square(&v01) 265 | v02.Add(&x.B0, &x.B2) 266 | v02.Square(&v02) 267 | v12.Add(&x.B1, &x.B2) 268 | v12.Square(&v12) 269 | 270 | z.B0.Sub(&v12, &v1).SubAssign(&v2) 271 | { // begin: inline z.B0.MulByNonResidue(&z.B0) 272 | var buf e2 273 | buf.Set(&z.B0) 274 | z.B0.A1.Add(&buf.A0, &buf.A1) 275 | { // begin: inline MulByNonResidue(&(z.B0).A0, &buf.A1) 276 | (&(z.B0).A0).Neg(&buf.A1) 277 | } // end: inline MulByNonResidue(&(z.B0).A0, &buf.A1) 278 | z.B0.A0.AddAssign(&buf.A0) 279 | } // end: inline z.B0.MulByNonResidue(&z.B0) 280 | z.B0.AddAssign(&v0) 281 | { // begin: inline z.B1.MulByNonResidue(&v2) 282 | var buf e2 283 | buf.Set(&v2) 284 | z.B1.A1.Add(&buf.A0, &buf.A1) 285 | { // begin: inline MulByNonResidue(&(z.B1).A0, &buf.A1) 286 | (&(z.B1).A0).Neg(&buf.A1) 287 | } // end: inline MulByNonResidue(&(z.B1).A0, &buf.A1) 288 | z.B1.A0.AddAssign(&buf.A0) 289 | } // end: inline z.B1.MulByNonResidue(&v2) 290 | z.B1.AddAssign(&v01).SubAssign(&v0).SubAssign(&v1) 291 | 292 | z.B2.Add(&v02, &v1).SubAssign(&v0).SubAssign(&v2) 293 | return z 294 | } 295 | 296 | // Square3 squares a e6 297 | func (z *e6) Square3(x *e6) *e6 { 298 | // CH-SQR2 from from Section 4 of https://eprint.iacr.org/2006/471.pdf 299 | var s0, s1, s2, s3, s4 e2 300 | s0.Square(&x.B0) 301 | s1.Mul(&x.B0, &x.B1).Double(&s1) 302 | s2.Sub(&x.B0, &x.B1).AddAssign(&x.B2).Square(&s2) 303 | s3.Mul(&x.B1, &x.B2).Double(&s3) 304 | s4.Square(&x.B2) 305 | { // begin: inline z.B0.MulByNonResidue(&s3) 306 | var buf e2 307 | buf.Set(&s3) 308 | z.B0.A1.Add(&buf.A0, &buf.A1) 309 | { // begin: inline MulByNonResidue(&(z.B0).A0, &buf.A1) 310 | (&(z.B0).A0).Neg(&buf.A1) 311 | } // end: inline MulByNonResidue(&(z.B0).A0, &buf.A1) 312 | z.B0.A0.AddAssign(&buf.A0) 313 | } // end: inline z.B0.MulByNonResidue(&s3) 314 | z.B0.AddAssign(&s0) 315 | { // begin: inline z.B1.MulByNonResidue(&s4) 316 | var buf e2 317 | buf.Set(&s4) 318 | z.B1.A1.Add(&buf.A0, &buf.A1) 319 | { // begin: inline MulByNonResidue(&(z.B1).A0, &buf.A1) 320 | (&(z.B1).A0).Neg(&buf.A1) 321 | } // end: inline MulByNonResidue(&(z.B1).A0, &buf.A1) 322 | z.B1.A0.AddAssign(&buf.A0) 323 | } // end: inline z.B1.MulByNonResidue(&s4) 324 | z.B1.AddAssign(&s1) 325 | z.B2.Add(&s1, &s2).AddAssign(&s3).SubAssign(&s0).SubAssign(&s4) 326 | return z 327 | } 328 | 329 | // Inverse an element in e6 330 | func (z *e6) Inverse(x *e6) *e6 { 331 | // Algorithm 17 from https://eprint.iacr.org/2010/354.pdf 332 | // step 9 is wrong in the paper! 333 | 334 | // memalloc 335 | var t [7]e2 336 | var c [3]e2 337 | var buf e2 338 | 339 | t[0].Square(&x.B0) // step 1 340 | t[1].Square(&x.B1) // step 2 341 | t[2].Square(&x.B2) // step 3 342 | t[3].Mul(&x.B0, &x.B1) // step 4 343 | t[4].Mul(&x.B0, &x.B2) // step 5 344 | t[5].Mul(&x.B1, &x.B2) // step 6 345 | 346 | // step 7 347 | { // begin: inline c[0].MulByNonResidue(&t[5]) 348 | var buf e2 349 | buf.Set(&t[5]) 350 | c[0].A1.Add(&buf.A0, &buf.A1) 351 | { // begin: inline MulByNonResidue(&(c[0]).A0, &buf.A1) 352 | (&(c[0]).A0).Neg(&buf.A1) 353 | } // end: inline MulByNonResidue(&(c[0]).A0, &buf.A1) 354 | c[0].A0.AddAssign(&buf.A0) 355 | } // end: inline c[0].MulByNonResidue(&t[5]) 356 | c[0].Neg(&c[0]).AddAssign(&t[0]) 357 | 358 | // step 8 359 | { // begin: inline c[1].MulByNonResidue(&t[2]) 360 | var buf e2 361 | buf.Set(&t[2]) 362 | c[1].A1.Add(&buf.A0, &buf.A1) 363 | { // begin: inline MulByNonResidue(&(c[1]).A0, &buf.A1) 364 | (&(c[1]).A0).Neg(&buf.A1) 365 | } // end: inline MulByNonResidue(&(c[1]).A0, &buf.A1) 366 | c[1].A0.AddAssign(&buf.A0) 367 | } // end: inline c[1].MulByNonResidue(&t[2]) 368 | c[1].SubAssign(&t[3]) 369 | 370 | c[2].Sub(&t[1], &t[4]) // step 9 is wrong in 2010/354! 371 | 372 | // steps 10, 11, 12 373 | t[6].Mul(&x.B2, &c[1]) 374 | buf.Mul(&x.B1, &c[2]) 375 | t[6].AddAssign(&buf) 376 | { // begin: inline t[6].MulByNonResidue(&t[6]) 377 | var buf e2 378 | buf.Set(&t[6]) 379 | t[6].A1.Add(&buf.A0, &buf.A1) 380 | { // begin: inline MulByNonResidue(&(t[6]).A0, &buf.A1) 381 | (&(t[6]).A0).Neg(&buf.A1) 382 | } // end: inline MulByNonResidue(&(t[6]).A0, &buf.A1) 383 | t[6].A0.AddAssign(&buf.A0) 384 | } // end: inline t[6].MulByNonResidue(&t[6]) 385 | buf.Mul(&x.B0, &c[0]) 386 | t[6].AddAssign(&buf) 387 | 388 | t[6].Inverse(&t[6]) // step 13 389 | z.B0.Mul(&c[0], &t[6]) // step 14 390 | z.B1.Mul(&c[1], &t[6]) // step 15 391 | z.B2.Mul(&c[2], &t[6]) // step 16 392 | 393 | return z 394 | } 395 | 396 | // MulByNonResidue multiplies a e2 by (1,1) 397 | func (z *e2) MulByNonResidue(x *e2) *e2 { 398 | var buf e2 399 | buf.Set(x) 400 | z.A1.Add(&buf.A0, &buf.A1) 401 | { // begin: inline MulByNonResidue(&(z).A0, &buf.A1) 402 | (&(z).A0).Neg(&buf.A1) 403 | } // end: inline MulByNonResidue(&(z).A0, &buf.A1) 404 | z.A0.AddAssign(&buf.A0) 405 | return z 406 | } 407 | 408 | // MulByNonResidueInv multiplies a e2 by (1,1)^{-1} 409 | func (z *e2) MulByNonResidueInv(x *e2) *e2 { 410 | // (z).A0 = ((x).A0 + (x).A1)/2 411 | // (z).A1 = ((x).A1 - (x).A0)/2 412 | buf := *(x) 413 | (z).A0.Add(&buf.A0, &buf.A1) 414 | (z).A1.Sub(&buf.A1, &buf.A0) 415 | twoInv := fp.Element{ 416 | 1730508156817200468, 417 | 9606178027640717313, 418 | 7150789853162776431, 419 | 7936136305760253186, 420 | 15245073033536294050, 421 | 1728177566264616342, 422 | } 423 | (z).A0.MulAssign(&twoInv) 424 | (z).A1.MulAssign(&twoInv) 425 | return z 426 | } 427 | -------------------------------------------------------------------------------- /ecc/bls381/fp/arith.go: -------------------------------------------------------------------------------- 1 | package fp 2 | 3 | import ( 4 | "math/bits" 5 | ) 6 | 7 | func madd(a, b, t, u, v uint64) (uint64, uint64, uint64) { 8 | var carry uint64 9 | hi, lo := bits.Mul64(a, b) 10 | v, carry = bits.Add64(lo, v, 0) 11 | u, carry = bits.Add64(hi, u, carry) 12 | t, _ = bits.Add64(t, 0, carry) 13 | return t, u, v 14 | } 15 | 16 | // madd0 hi = a*b + c (discards lo bits) 17 | func madd0(a, b, c uint64) (hi uint64) { 18 | var carry, lo uint64 19 | hi, lo = bits.Mul64(a, b) 20 | _, carry = bits.Add64(lo, c, 0) 21 | hi, _ = bits.Add64(hi, 0, carry) 22 | return 23 | } 24 | 25 | // madd1 hi, lo = a*b + c 26 | func madd1(a, b, c uint64) (hi uint64, lo uint64) { 27 | var carry uint64 28 | hi, lo = bits.Mul64(a, b) 29 | lo, carry = bits.Add64(lo, c, 0) 30 | hi, _ = bits.Add64(hi, 0, carry) 31 | return 32 | } 33 | 34 | // madd2 hi, lo = a*b + c + d 35 | func madd2(a, b, c, d uint64) (hi uint64, lo uint64) { 36 | var carry uint64 37 | hi, lo = bits.Mul64(a, b) 38 | c, carry = bits.Add64(c, d, 0) 39 | hi, _ = bits.Add64(hi, 0, carry) 40 | lo, carry = bits.Add64(lo, c, 0) 41 | hi, _ = bits.Add64(hi, 0, carry) 42 | return 43 | } 44 | 45 | // madd2s superhi, hi, lo = 2*a*b + c + d + e 46 | func madd2s(a, b, c, d, e uint64) (superhi, hi, lo uint64) { 47 | var carry, sum uint64 48 | 49 | hi, lo = bits.Mul64(a, b) 50 | lo, carry = bits.Add64(lo, lo, 0) 51 | hi, superhi = bits.Add64(hi, hi, carry) 52 | 53 | sum, carry = bits.Add64(c, e, 0) 54 | hi, _ = bits.Add64(hi, 0, carry) 55 | lo, carry = bits.Add64(lo, sum, 0) 56 | hi, _ = bits.Add64(hi, 0, carry) 57 | hi, _ = bits.Add64(hi, 0, d) 58 | return 59 | } 60 | 61 | func madd1s(a, b, d, e uint64) (superhi, hi, lo uint64) { 62 | var carry uint64 63 | 64 | hi, lo = bits.Mul64(a, b) 65 | lo, carry = bits.Add64(lo, lo, 0) 66 | hi, superhi = bits.Add64(hi, hi, carry) 67 | lo, carry = bits.Add64(lo, e, 0) 68 | hi, _ = bits.Add64(hi, 0, carry) 69 | hi, _ = bits.Add64(hi, 0, d) 70 | return 71 | } 72 | 73 | func madd2sb(a, b, c, e uint64) (superhi, hi, lo uint64) { 74 | var carry, sum uint64 75 | 76 | hi, lo = bits.Mul64(a, b) 77 | lo, carry = bits.Add64(lo, lo, 0) 78 | hi, superhi = bits.Add64(hi, hi, carry) 79 | 80 | sum, carry = bits.Add64(c, e, 0) 81 | hi, _ = bits.Add64(hi, 0, carry) 82 | lo, carry = bits.Add64(lo, sum, 0) 83 | hi, _ = bits.Add64(hi, 0, carry) 84 | return 85 | } 86 | 87 | func madd1sb(a, b, e uint64) (superhi, hi, lo uint64) { 88 | var carry uint64 89 | 90 | hi, lo = bits.Mul64(a, b) 91 | lo, carry = bits.Add64(lo, lo, 0) 92 | hi, superhi = bits.Add64(hi, hi, carry) 93 | lo, carry = bits.Add64(lo, e, 0) 94 | hi, _ = bits.Add64(hi, 0, carry) 95 | return 96 | } 97 | 98 | func madd3(a, b, c, d, e uint64) (hi uint64, lo uint64) { 99 | var carry uint64 100 | hi, lo = bits.Mul64(a, b) 101 | c, carry = bits.Add64(c, d, 0) 102 | hi, _ = bits.Add64(hi, 0, carry) 103 | lo, carry = bits.Add64(lo, c, 0) 104 | hi, _ = bits.Add64(hi, e, carry) 105 | return 106 | } 107 | -------------------------------------------------------------------------------- /ecc/bls381/fr/arith.go: -------------------------------------------------------------------------------- 1 | package fr 2 | 3 | import ( 4 | "math/bits" 5 | ) 6 | 7 | func madd(a, b, t, u, v uint64) (uint64, uint64, uint64) { 8 | var carry uint64 9 | hi, lo := bits.Mul64(a, b) 10 | v, carry = bits.Add64(lo, v, 0) 11 | u, carry = bits.Add64(hi, u, carry) 12 | t, _ = bits.Add64(t, 0, carry) 13 | return t, u, v 14 | } 15 | 16 | // madd0 hi = a*b + c (discards lo bits) 17 | func madd0(a, b, c uint64) (hi uint64) { 18 | var carry, lo uint64 19 | hi, lo = bits.Mul64(a, b) 20 | _, carry = bits.Add64(lo, c, 0) 21 | hi, _ = bits.Add64(hi, 0, carry) 22 | return 23 | } 24 | 25 | // madd1 hi, lo = a*b + c 26 | func madd1(a, b, c uint64) (hi uint64, lo uint64) { 27 | var carry uint64 28 | hi, lo = bits.Mul64(a, b) 29 | lo, carry = bits.Add64(lo, c, 0) 30 | hi, _ = bits.Add64(hi, 0, carry) 31 | return 32 | } 33 | 34 | // madd2 hi, lo = a*b + c + d 35 | func madd2(a, b, c, d uint64) (hi uint64, lo uint64) { 36 | var carry uint64 37 | hi, lo = bits.Mul64(a, b) 38 | c, carry = bits.Add64(c, d, 0) 39 | hi, _ = bits.Add64(hi, 0, carry) 40 | lo, carry = bits.Add64(lo, c, 0) 41 | hi, _ = bits.Add64(hi, 0, carry) 42 | return 43 | } 44 | 45 | // madd2s superhi, hi, lo = 2*a*b + c + d + e 46 | func madd2s(a, b, c, d, e uint64) (superhi, hi, lo uint64) { 47 | var carry, sum uint64 48 | 49 | hi, lo = bits.Mul64(a, b) 50 | lo, carry = bits.Add64(lo, lo, 0) 51 | hi, superhi = bits.Add64(hi, hi, carry) 52 | 53 | sum, carry = bits.Add64(c, e, 0) 54 | hi, _ = bits.Add64(hi, 0, carry) 55 | lo, carry = bits.Add64(lo, sum, 0) 56 | hi, _ = bits.Add64(hi, 0, carry) 57 | hi, _ = bits.Add64(hi, 0, d) 58 | return 59 | } 60 | 61 | func madd1s(a, b, d, e uint64) (superhi, hi, lo uint64) { 62 | var carry uint64 63 | 64 | hi, lo = bits.Mul64(a, b) 65 | lo, carry = bits.Add64(lo, lo, 0) 66 | hi, superhi = bits.Add64(hi, hi, carry) 67 | lo, carry = bits.Add64(lo, e, 0) 68 | hi, _ = bits.Add64(hi, 0, carry) 69 | hi, _ = bits.Add64(hi, 0, d) 70 | return 71 | } 72 | 73 | func madd2sb(a, b, c, e uint64) (superhi, hi, lo uint64) { 74 | var carry, sum uint64 75 | 76 | hi, lo = bits.Mul64(a, b) 77 | lo, carry = bits.Add64(lo, lo, 0) 78 | hi, superhi = bits.Add64(hi, hi, carry) 79 | 80 | sum, carry = bits.Add64(c, e, 0) 81 | hi, _ = bits.Add64(hi, 0, carry) 82 | lo, carry = bits.Add64(lo, sum, 0) 83 | hi, _ = bits.Add64(hi, 0, carry) 84 | return 85 | } 86 | 87 | func madd1sb(a, b, e uint64) (superhi, hi, lo uint64) { 88 | var carry uint64 89 | 90 | hi, lo = bits.Mul64(a, b) 91 | lo, carry = bits.Add64(lo, lo, 0) 92 | hi, superhi = bits.Add64(hi, hi, carry) 93 | lo, carry = bits.Add64(lo, e, 0) 94 | hi, _ = bits.Add64(hi, 0, carry) 95 | return 96 | } 97 | 98 | func madd3(a, b, c, d, e uint64) (hi uint64, lo uint64) { 99 | var carry uint64 100 | hi, lo = bits.Mul64(a, b) 101 | c, carry = bits.Add64(c, d, 0) 102 | hi, _ = bits.Add64(hi, 0, carry) 103 | lo, carry = bits.Add64(lo, c, 0) 104 | hi, _ = bits.Add64(hi, e, carry) 105 | return 106 | } 107 | -------------------------------------------------------------------------------- /ecc/bls381/pairing.go: -------------------------------------------------------------------------------- 1 | package bls381 2 | 3 | // FinalExponentiation computes the final expo x**(p**6-1)(p**2+1)(p**4 - p**2 +1)/r 4 | func (curve *Curve) FinalExponentiation(z *e12, _z ...*e12) e12 { 5 | var result e12 6 | result.Set(z) 7 | 8 | // if additional parameters are provided, multiply them into z 9 | for _, e := range _z { 10 | result.Mul(&result, e) 11 | } 12 | 13 | result.FinalExponentiation(&result) 14 | 15 | return result 16 | } 17 | 18 | // MillerLoop Miller loop 19 | func (curve *Curve) MillerLoop(P G1Affine, Q G2Affine, result *e12) *e12 { 20 | 21 | // init result 22 | result.SetOne() 23 | 24 | if P.IsInfinity() || Q.IsInfinity() { 25 | return result 26 | } 27 | 28 | // the line goes through QCur and QNext 29 | var QCur, QNext, QNextNeg G2Jac 30 | var QNeg G2Affine 31 | 32 | // Stores -Q 33 | QNeg.Neg(&Q) 34 | 35 | // init QCur with Q 36 | Q.ToJacobian(&QCur) 37 | 38 | var lEval lineEvalRes 39 | 40 | // Miller loop 41 | for i := len(curve.loopCounter) - 2; i >= 0; i-- { 42 | QNext.Set(&QCur) 43 | QNext.Double() 44 | QNextNeg.Neg(&QNext) 45 | 46 | result.Square(result) 47 | 48 | // evaluates line though Qcur,2Qcur at P 49 | lineEvalJac(QCur, QNextNeg, &P, &lEval) 50 | lEval.mulAssign(result) 51 | 52 | if curve.loopCounter[i] == 1 { 53 | // evaluates line through 2Qcur, Q at P 54 | lineEvalAffine(QNext, Q, &P, &lEval) 55 | lEval.mulAssign(result) 56 | 57 | QNext.AddMixed(&Q) 58 | 59 | } else if curve.loopCounter[i] == -1 { 60 | // evaluates line through 2Qcur, -Q at P 61 | lineEvalAffine(QNext, QNeg, &P, &lEval) 62 | lEval.mulAssign(result) 63 | 64 | QNext.AddMixed(&QNeg) 65 | } 66 | QCur.Set(&QNext) 67 | } 68 | 69 | return result 70 | } 71 | 72 | // lineEval computes the evaluation of the line through Q, R (on the twist) at P 73 | // Q, R are in jacobian coordinates 74 | // The case in which Q=R=Infinity is not handled as this doesn't happen in the SNARK pairing 75 | func lineEvalJac(Q, R G2Jac, P *G1Affine, result *lineEvalRes) { 76 | // converts Q and R to projective coords 77 | Q.ToProjFromJac() 78 | R.ToProjFromJac() 79 | 80 | // line eq: w^3*(QyRz-QzRy)x + w^2*(QzRx - QxRz)y + w^5*(QxRy-QyRxz) 81 | // result.r1 = QyRz-QzRy 82 | // result.r0 = QzRx - QxRz 83 | // result.r2 = QxRy-QyRxz 84 | 85 | result.r1.Mul(&Q.Y, &R.Z) 86 | result.r0.Mul(&Q.Z, &R.X) 87 | result.r2.Mul(&Q.X, &R.Y) 88 | 89 | Q.Z.Mul(&Q.Z, &R.Y) 90 | Q.X.Mul(&Q.X, &R.Z) 91 | Q.Y.Mul(&Q.Y, &R.X) 92 | 93 | result.r1.Sub(&result.r1, &Q.Z) 94 | result.r0.Sub(&result.r0, &Q.X) 95 | result.r2.Sub(&result.r2, &Q.Y) 96 | 97 | // multiply P.Z by coeffs[2] in case P is infinity 98 | result.r1.MulByElement(&result.r1, &P.X) 99 | result.r0.MulByElement(&result.r0, &P.Y) 100 | //result.r2.MulByElement(&result.r2, &P.Z) 101 | } 102 | 103 | // Same as above but R is in affine coords 104 | func lineEvalAffine(Q G2Jac, R G2Affine, P *G1Affine, result *lineEvalRes) { 105 | 106 | // converts Q and R to projective coords 107 | Q.ToProjFromJac() 108 | 109 | // line eq: w^3*(QyRz-QzRy)x + w^2*(QzRx - QxRz)y + w^5*(QxRy-QyRxz) 110 | // result.r1 = QyRz-QzRy 111 | // result.r0 = QzRx - QxRz 112 | // result.r2 = QxRy-QyRxz 113 | 114 | result.r1.Set(&Q.Y) 115 | result.r0.Mul(&Q.Z, &R.X) 116 | result.r2.Mul(&Q.X, &R.Y) 117 | 118 | Q.Z.Mul(&Q.Z, &R.Y) 119 | Q.Y.Mul(&Q.Y, &R.X) 120 | 121 | result.r1.Sub(&result.r1, &Q.Z) 122 | result.r0.Sub(&result.r0, &Q.X) 123 | result.r2.Sub(&result.r2, &Q.Y) 124 | 125 | // multiply P.Z by coeffs[2] in case P is infinity 126 | result.r1.MulByElement(&result.r1, &P.X) 127 | result.r0.MulByElement(&result.r0, &P.Y) 128 | // result.r2.MulByElement(&result.r2, &P.Z) 129 | } 130 | 131 | type lineEvalRes struct { 132 | r0 e2 // c0.b1 133 | r1 e2 // c1.b1 134 | r2 e2 // c1.b2 135 | } 136 | 137 | func (l *lineEvalRes) mulAssign(z *e12) *e12 { 138 | 139 | var a, b, c e12 140 | 141 | a.MulByVWNRInv(z, &l.r1) 142 | b.MulByV2NRInv(z, &l.r0) 143 | c.MulByWNRInv(z, &l.r2) 144 | z.Add(&a, &b).Add(z, &c) 145 | 146 | return z 147 | } 148 | -------------------------------------------------------------------------------- /ecc/bls381Utils/bls381Utils.go: -------------------------------------------------------------------------------- 1 | package bls381Utils 2 | 3 | import ( 4 | "crypto/rand" 5 | "math/big" 6 | "scrypto/ecc/bls381" 7 | "scrypto/ecc/bls381/fr" 8 | ) 9 | 10 | var ( 11 | BLSCurve = bls381.BLS381() 12 | BaseG1 = BLSCurve.G1Gen 13 | BaseG2 = BLSCurve.G2Gen 14 | ) 15 | 16 | type G1 = bls381.G1Jac 17 | type G2 = bls381.G2Jac 18 | type GT = bls381.PairingResult 19 | 20 | const ( 21 | bits = 256 22 | ) 23 | 24 | func G1ScalarBaseMult(a *big.Int) *G1 { 25 | var b fr.Element 26 | b.SetBigInt(a) 27 | 28 | return new(G1).ScalarMulByGen(BLSCurve, b) 29 | } 30 | 31 | func RandomG1() (k *big.Int, K *G1, err error) { 32 | for { 33 | k, err = rand.Prime(rand.Reader, bits) 34 | if err != nil { 35 | return nil, nil, err 36 | } 37 | if k.Sign() > 0 { 38 | break 39 | } 40 | } 41 | return k, G1ScalarBaseMult(k), nil 42 | } 43 | 44 | func RandomG2() (k *big.Int, K *G2, err error) { 45 | for { 46 | k, err = rand.Prime(rand.Reader, bits) 47 | if err != nil { 48 | return nil, nil, err 49 | } 50 | if k.Sign() > 0 { 51 | break 52 | } 53 | } 54 | K = G2ScalarBaseMult(k) 55 | return k, K, nil 56 | } 57 | 58 | func G1ScalarMult(a *G1, b *big.Int) *G1 { 59 | var c fr.Element 60 | c.SetBigInt(b) 61 | return new(G1).ScalarMul(BLSCurve, a, c) 62 | } 63 | 64 | func G1Add(a, b *G1) *G1 { 65 | a1 := new(G1).Set(a) 66 | return a1.Add(BLSCurve, b) 67 | } 68 | 69 | func G1Neg(a *G1) *G1 { 70 | return new(G1).Neg(a) 71 | } 72 | 73 | func G1Equal(a, b *G1) bool { 74 | return a.Equal(b) 75 | } 76 | 77 | func G2ScalarBaseMult(a *big.Int) *G2 { 78 | var b fr.Element 79 | b.SetBigInt(a) 80 | return new(G2).ScalarMulByGen(BLSCurve, b) 81 | } 82 | 83 | func G2ScalarMult(a *G2, b *big.Int) *G2 { 84 | var c fr.Element 85 | c.SetBigInt(b) 86 | return new(G2).ScalarMul(BLSCurve, a, c) 87 | } 88 | 89 | func G2Add(a, b *G2) *G2 { 90 | a1 := new(G2).Set(a) 91 | return a1.Add(BLSCurve, b) 92 | } 93 | 94 | func G2Neg(a *G2) *G2 { 95 | return new(G2).Neg(a) 96 | } 97 | 98 | func G2Equal(a, b *G2) bool { 99 | return a.Equal(b) 100 | } 101 | 102 | func BLSPair(a *G1, b *G2) *GT { 103 | var res GT 104 | var aA bls381.G1Affine 105 | var bA bls381.G2Affine 106 | a.ToAffineFromJac(&aA) 107 | b.ToAffineFromJac(&bA) 108 | res = BLSCurve.FinalExponentiation(BLSCurve.MillerLoop(aA, bA, &res)) 109 | return &res 110 | } 111 | -------------------------------------------------------------------------------- /ecc/bls381Utils/bls381Utils_test.go: -------------------------------------------------------------------------------- 1 | package bls381Utils 2 | 3 | import ( 4 | "fmt" 5 | "math/big" 6 | "testing" 7 | ) 8 | 9 | func TestBLSPair(t *testing.T) { 10 | a := G1ScalarBaseMult(new(big.Int).SetInt64(1)) 11 | b := G2ScalarBaseMult(new(big.Int).SetInt64(2)) 12 | c := new(big.Int).SetBytes([]byte("Hello")) 13 | at := G1ScalarMult(a, c) 14 | bt := G2ScalarMult(b, c) 15 | acb := BLSPair(at, b) 16 | abc := BLSPair(a, bt) 17 | fmt.Println("pair result:", acb.Equal(abc)) 18 | } 19 | 20 | func TestG1ScalarBaseMult(t *testing.T) { 21 | baseG1 := G1ScalarBaseMult(new(big.Int).SetUint64(1)) 22 | fmt.Println("baseG1:", baseG1) 23 | } 24 | 25 | func TestG2ScalarBaseMult(t *testing.T) { 26 | baseG2 := G2ScalarBaseMult(new(big.Int).SetUint64(1)) 27 | fmt.Println("baseG2:", baseG2) 28 | } 29 | -------------------------------------------------------------------------------- /ecc/bn256/bn256.go: -------------------------------------------------------------------------------- 1 | package bn256 2 | 3 | import ( 4 | "math/big" 5 | "scrypto/ecc" 6 | "sync" 7 | 8 | "scrypto/ecc/bn256/fp" 9 | ) 10 | 11 | // generate code for field tower, curve groups 12 | // add -testpoints to generate test points using sage 13 | // TODO g1_test.go, g2_test.go tests currently fail---just delete those files 14 | //go:generate go run ../internal/generator.go -out . -package bn256 -t 4965661367192848881 -p 21888242871839275222246405745257275088696311157297823662689037894645226208583 -r 21888242871839275222246405745257275088548364400416034343698204186575808495617 -fp2 -1 -fp6 9,1 15 | 16 | // E: y**2=x**3+3 17 | // Etwist: y**2 = x**3+3*(u+9)**-1 18 | 19 | var bn256 Curve 20 | var initOnce sync.Once 21 | 22 | // ID bn256 ID 23 | const ID = ecc.BN256 24 | 25 | // parameters for pippenger ScalarMulByGen 26 | const sGen = 4 27 | const bGen = sGen 28 | 29 | type PairingResult = e12 30 | 31 | // BN256 returns BN256 curve 32 | func BN256() *Curve { 33 | initOnce.Do(initBN256) 34 | return &bn256 35 | } 36 | 37 | // Curve represents the BLS381 curve and pre-computed constants 38 | type Curve struct { 39 | B fp.Element // A, B coefficients of the curve x^3 = y^2 +AX+b 40 | 41 | G1Gen G1Jac // generator of torsion group G1Jac 42 | G2Gen G2Jac // generator of torsion group G2Jac 43 | 44 | g1Infinity G1Jac // infinity (in Jacobian coords) 45 | g2Infinity G2Jac 46 | 47 | // TODO store this number as a MAX_SIZE constant, or with build tags 48 | // NAF decomposition takes 65 trits for bn256 but only 64 trits for bls377 49 | //loopCounter [128]int8 // NAF decomposition of t-1, t is the trace of the Frobenius 50 | loopCounter [66]int8 // NAF decomposition of t-1, t is the trace of the Frobenius 51 | 52 | // precomputed values for ScalarMulByGen 53 | tGenG1 [((1 << bGen) - 1)]G1Jac 54 | tGenG2 [((1 << bGen) - 1)]G2Jac 55 | } 56 | 57 | func initBN256() { 58 | 59 | // A, B coeffs of the curve in Mont form 60 | bn256.B.SetUint64(3) 61 | 62 | // Setting G1Jac 63 | bn256.G1Gen.X.SetString("20567171726433170376993012834626974355708098753738075953327671604980729474588") 64 | bn256.G1Gen.Y.SetString("14259118686601658563517637559143782061303537174604067025175876803301021346267") 65 | bn256.G1Gen.Z.SetString("1") 66 | 67 | // Setting G2Jac 68 | bn256.G2Gen.X.SetString("14433365730775072582213482468844163390964025019096075555058505630999708262443", 69 | "3683446723006852480794963570030936618743148392137679437247363531986401769417") 70 | bn256.G2Gen.Y.SetString("21253271987667943455369004300257637004831224612428754877033343975009216128128", 71 | "12495620673937637012904672587588023149812491484245871073230980321212840773339") 72 | bn256.G2Gen.Z.SetString("1", 73 | "0") 74 | 75 | // Setting the loop counter for Miller loop in NAF form 76 | //T, _ := new(big.Int).SetString("147946756881789318990833708069417712966", 10) 77 | T, _ := new(big.Int).SetString("29793968203157093288", 10) 78 | ecc.NafDecomposition(T, bn256.loopCounter[:]) 79 | 80 | // infinity point G1 81 | bn256.g1Infinity.X.SetOne() 82 | bn256.g1Infinity.Y.SetOne() 83 | 84 | // infinity point G2 85 | bn256.g2Infinity.X.SetOne() 86 | bn256.g2Infinity.Y.SetOne() 87 | 88 | // precomputed values for ScalarMulByGen 89 | bn256.tGenG1[0].Set(&bn256.G1Gen) 90 | for j := 1; j < len(bn256.tGenG1)-1; j = j + 2 { 91 | bn256.tGenG1[j].Set(&bn256.tGenG1[j/2]).Double() 92 | bn256.tGenG1[j+1].Set(&bn256.tGenG1[(j+1)/2]).Add(&bn256, &bn256.tGenG1[j/2]) 93 | } 94 | bn256.tGenG2[0].Set(&bn256.G2Gen) 95 | for j := 1; j < len(bn256.tGenG2)-1; j = j + 2 { 96 | bn256.tGenG2[j].Set(&bn256.tGenG2[j/2]).Double() 97 | bn256.tGenG2[j+1].Set(&bn256.tGenG2[(j+1)/2]).Add(&bn256, &bn256.tGenG2[j/2]) 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /ecc/bn256/e2.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 ConsenSys AG 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Code generated by gurvy/internal/generators DO NOT EDIT 16 | 17 | package bn256 18 | 19 | // Code generated by internal/fp2 DO NOT EDIT 20 | 21 | import ( 22 | "github.com/consensys/gurvy/bn256/fp" 23 | ) 24 | 25 | // e2 is a degree-two finite field extension of fp.Element: 26 | // A0 + A1u where u^2 == -1 is a quadratic nonresidue in fp 27 | 28 | type e2 struct { 29 | A0, A1 fp.Element 30 | } 31 | 32 | // SetString sets a e2 element from strings 33 | func (z *e2) SetString(s1, s2 string) *e2 { 34 | z.A0.SetString(s1) 35 | z.A1.SetString(s2) 36 | return z 37 | } 38 | 39 | func (z *e2) SetZero() *e2 { 40 | z.A0.SetZero() 41 | z.A1.SetZero() 42 | return z 43 | } 44 | 45 | // Clone returns a copy of self 46 | func (z *e2) Clone() *e2 { 47 | return &e2{ 48 | A0: z.A0, 49 | A1: z.A1, 50 | } 51 | } 52 | 53 | // Set sets an e2 from x 54 | func (z *e2) Set(x *e2) *e2 { 55 | z.A0.Set(&x.A0) 56 | z.A1.Set(&x.A1) 57 | return z 58 | } 59 | 60 | // Set sets z to 1 61 | func (z *e2) SetOne() *e2 { 62 | z.A0.SetOne() 63 | z.A1.SetZero() 64 | return z 65 | } 66 | 67 | // SetRandom sets a0 and a1 to random values 68 | func (z *e2) SetRandom() *e2 { 69 | z.A0.SetRandom() 70 | z.A1.SetRandom() 71 | return z 72 | } 73 | 74 | // Equal returns true if the two elements are equal, fasle otherwise 75 | func (z *e2) Equal(x *e2) bool { 76 | return z.A0.Equal(&x.A0) && z.A1.Equal(&x.A1) 77 | } 78 | 79 | // Equal returns true if the two elements are equal, fasle otherwise 80 | func (z *e2) IsZero() bool { 81 | return z.A0.IsZero() && z.A1.IsZero() 82 | } 83 | 84 | // Neg negates an e2 element 85 | func (z *e2) Neg(x *e2) *e2 { 86 | z.A0.Neg(&x.A0) 87 | z.A1.Neg(&x.A1) 88 | return z 89 | } 90 | 91 | // String implements Stringer interface for fancy printing 92 | func (z *e2) String() string { 93 | return (z.A0.String() + "+" + z.A1.String() + "*u") 94 | } 95 | 96 | // ToMont converts to mont form 97 | func (z *e2) ToMont() *e2 { 98 | z.A0.ToMont() 99 | z.A1.ToMont() 100 | return z 101 | } 102 | 103 | // FromMont converts from mont form 104 | func (z *e2) FromMont() *e2 { 105 | z.A0.FromMont() 106 | z.A1.FromMont() 107 | return z 108 | } 109 | 110 | // Add adds two elements of e2 111 | func (z *e2) Add(x, y *e2) *e2 { 112 | z.A0.Add(&x.A0, &y.A0) 113 | z.A1.Add(&x.A1, &y.A1) 114 | return z 115 | } 116 | 117 | // AddAssign adds x to z 118 | func (z *e2) AddAssign(x *e2) *e2 { 119 | z.A0.AddAssign(&x.A0) 120 | z.A1.AddAssign(&x.A1) 121 | return z 122 | } 123 | 124 | // Sub two elements of e2 125 | func (z *e2) Sub(x, y *e2) *e2 { 126 | z.A0.Sub(&x.A0, &y.A0) 127 | z.A1.Sub(&x.A1, &y.A1) 128 | return z 129 | } 130 | 131 | // SubAssign subs x from z 132 | func (z *e2) SubAssign(x *e2) *e2 { 133 | z.A0.SubAssign(&x.A0) 134 | z.A1.SubAssign(&x.A1) 135 | return z 136 | } 137 | 138 | // Double doubles an e2 element 139 | func (z *e2) Double(x *e2) *e2 { 140 | z.A0.Double(&x.A0) 141 | z.A1.Double(&x.A1) 142 | return z 143 | } 144 | 145 | // Mul sets z to the e2-product of x,y, returns z 146 | func (z *e2) Mul(x, y *e2) *e2 { 147 | // (a+bu)*(c+du) == (ac+(-1)*bd) + (ad+bc)u where u^2 == -1 148 | // Karatsuba: 3 fp multiplications instead of 4 149 | // [1]: ac 150 | // [2]: bd 151 | // [3]: (a+b)*(c+d) 152 | // Then z.A0: [1] + (-1)*[2] 153 | // Then z.A1: [3] - [2] - [1] 154 | var ac, bd, cplusd, aplusbcplusd fp.Element 155 | 156 | ac.Mul(&x.A0, &y.A0) // [1]: ac 157 | bd.Mul(&x.A1, &y.A1) // [2]: bd 158 | cplusd.Add(&y.A0, &y.A1) // c+d 159 | aplusbcplusd.Add(&x.A0, &x.A1) // a+b 160 | aplusbcplusd.MulAssign(&cplusd) // [3]: (a+b)*(c+d) 161 | z.A1.Add(&ac, &bd) // ad+bc, [2] + [1] 162 | z.A1.Sub(&aplusbcplusd, &z.A1) // z.A1: [3] - [2] - [1] 163 | z.A0.Sub(&ac, &bd) // z.A0: [1] - [2] 164 | return z 165 | } 166 | 167 | // MulAssign sets z to the e2-product of z,x returns z 168 | func (z *e2) MulAssign(x *e2) *e2 { 169 | // (a+bu)*(c+du) == (ac+(-1)*bd) + (ad+bc)u where u^2 == -1 170 | // Karatsuba: 3 fp multiplications instead of 4 171 | // [1]: ac 172 | // [2]: bd 173 | // [3]: (a+b)*(c+d) 174 | // Then z.A0: [1] + (-1)*[2] 175 | // Then z.A1: [3] - [2] - [1] 176 | var ac, bd, cplusd, aplusbcplusd fp.Element 177 | 178 | ac.Mul(&z.A0, &x.A0) // [1]: ac 179 | bd.Mul(&z.A1, &x.A1) // [2]: bd 180 | cplusd.Add(&x.A0, &x.A1) // c+d 181 | aplusbcplusd.Add(&z.A0, &z.A1) // a+b 182 | aplusbcplusd.MulAssign(&cplusd) // [3]: (a+b)*(c+d) 183 | z.A1.Add(&ac, &bd) // ad+bc, [2] + [1] 184 | z.A1.Sub(&aplusbcplusd, &z.A1) // z.A1: [3] - [2] - [1] 185 | z.A0.Sub(&ac, &bd) // z.A0: [1] - [2] 186 | return z 187 | } 188 | 189 | // Square sets z to the e2-product of x,x returns z 190 | func (z *e2) Square(x *e2) *e2 { 191 | // (a+bu)^2 == (a^2+(-1)*b^2) + (2ab)u where u^2 == -1 192 | // Complex method: 2 fp multiplications instead of 3 193 | // [1]: ab 194 | // [2]: (a+b)*(a+(-1)*b) 195 | // Then z.A0: [2] - (-1+1)*[1] 196 | // Then z.A1: 2[1] 197 | // optimize for quadratic nonresidue -1 198 | var aplusb fp.Element 199 | var result e2 200 | 201 | aplusb.Add(&x.A0, &x.A1) // a+b 202 | result.A0.Sub(&x.A0, &x.A1) // a-b 203 | result.A0.MulAssign(&aplusb) // [2]: (a+b)*(a-b) 204 | result.A1.Mul(&x.A0, &x.A1).Double(&result.A1) // [1]: ab 205 | 206 | z.Set(&result) 207 | 208 | return z 209 | } 210 | 211 | // MulByNonSquare multiplies an element by (0,1) 212 | // TODO deprecate in favor of inlined MulByNonResidue in fp6 package 213 | func (z *e2) MulByNonSquare(x *e2) *e2 { 214 | a := x.A0 215 | MulByNonResidue(&z.A0, &x.A1) 216 | z.A1 = a 217 | return z 218 | } 219 | 220 | // Inverse sets z to the e2-inverse of x, returns z 221 | func (z *e2) Inverse(x *e2) *e2 { 222 | // Algorithm 8 from https://eprint.iacr.org/2010/354.pdf 223 | var a0, a1, t0, t1 fp.Element 224 | 225 | a0 = x.A0 // = is slightly faster than Set() 226 | a1 = x.A1 // = is slightly faster than Set() 227 | 228 | t0.Square(&a0) // step 1 229 | t1.Square(&a1) // step 2 230 | t0.Add(&t0, &t1) // step 3 231 | t1.Inverse(&t0) // step 4 232 | z.A0.Mul(&a0, &t1) // step 5 233 | z.A1.Neg(&a1).MulAssign(&t1) // step 6 234 | 235 | return z 236 | } 237 | 238 | // MulByElement multiplies an element in e2 by an element in fp 239 | func (z *e2) MulByElement(x *e2, y *fp.Element) *e2 { 240 | var yCopy fp.Element 241 | yCopy.Set(y) 242 | z.A0.Mul(&x.A0, &yCopy) 243 | z.A1.Mul(&x.A1, &yCopy) 244 | return z 245 | } 246 | 247 | // Conjugate conjugates an element in e2 248 | func (z *e2) Conjugate(x *e2) *e2 { 249 | z.A0.Set(&x.A0) 250 | z.A1.Neg(&x.A1) 251 | return z 252 | } 253 | 254 | // MulByNonResidue multiplies a fp.Element by -1 255 | // It would be nice to make this a method of fp.Element but fp.Element is outside this package 256 | func MulByNonResidue(out, in *fp.Element) *fp.Element { 257 | (out).Neg(in) 258 | return out 259 | } 260 | 261 | // MulByNonResidueInv multiplies a fp.Element by -1^{-1} 262 | // It would be nice to make this a method of fp.Element but fp.Element is outside this package 263 | func MulByNonResidueInv(out, in *fp.Element) *fp.Element { 264 | // TODO this should be a no-op when out==in 265 | (out).Set(in) 266 | return out 267 | } 268 | -------------------------------------------------------------------------------- /ecc/bn256/fp/arith.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 ConsenSys AG 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Code generated by goff (v0.2.2) DO NOT EDIT 16 | 17 | // Package fp contains field arithmetic operations 18 | package fp 19 | 20 | import ( 21 | "math/bits" 22 | 23 | "golang.org/x/sys/cpu" 24 | ) 25 | 26 | var supportAdx = cpu.X86.HasADX && cpu.X86.HasBMI2 27 | 28 | func madd(a, b, t, u, v uint64) (uint64, uint64, uint64) { 29 | var carry uint64 30 | hi, lo := bits.Mul64(a, b) 31 | v, carry = bits.Add64(lo, v, 0) 32 | u, carry = bits.Add64(hi, u, carry) 33 | t, _ = bits.Add64(t, 0, carry) 34 | return t, u, v 35 | } 36 | 37 | // madd0 hi = a*b + c (discards lo bits) 38 | func madd0(a, b, c uint64) (hi uint64) { 39 | var carry, lo uint64 40 | hi, lo = bits.Mul64(a, b) 41 | _, carry = bits.Add64(lo, c, 0) 42 | hi, _ = bits.Add64(hi, 0, carry) 43 | return 44 | } 45 | 46 | // madd1 hi, lo = a*b + c 47 | func madd1(a, b, c uint64) (hi uint64, lo uint64) { 48 | var carry uint64 49 | hi, lo = bits.Mul64(a, b) 50 | lo, carry = bits.Add64(lo, c, 0) 51 | hi, _ = bits.Add64(hi, 0, carry) 52 | return 53 | } 54 | 55 | // madd2 hi, lo = a*b + c + d 56 | func madd2(a, b, c, d uint64) (hi uint64, lo uint64) { 57 | var carry uint64 58 | hi, lo = bits.Mul64(a, b) 59 | c, carry = bits.Add64(c, d, 0) 60 | hi, _ = bits.Add64(hi, 0, carry) 61 | lo, carry = bits.Add64(lo, c, 0) 62 | hi, _ = bits.Add64(hi, 0, carry) 63 | return 64 | } 65 | 66 | // madd2s superhi, hi, lo = 2*a*b + c + d + e 67 | func madd2s(a, b, c, d, e uint64) (superhi, hi, lo uint64) { 68 | var carry, sum uint64 69 | 70 | hi, lo = bits.Mul64(a, b) 71 | lo, carry = bits.Add64(lo, lo, 0) 72 | hi, superhi = bits.Add64(hi, hi, carry) 73 | 74 | sum, carry = bits.Add64(c, e, 0) 75 | hi, _ = bits.Add64(hi, 0, carry) 76 | lo, carry = bits.Add64(lo, sum, 0) 77 | hi, _ = bits.Add64(hi, 0, carry) 78 | hi, _ = bits.Add64(hi, 0, d) 79 | return 80 | } 81 | 82 | func madd1s(a, b, d, e uint64) (superhi, hi, lo uint64) { 83 | var carry uint64 84 | 85 | hi, lo = bits.Mul64(a, b) 86 | lo, carry = bits.Add64(lo, lo, 0) 87 | hi, superhi = bits.Add64(hi, hi, carry) 88 | lo, carry = bits.Add64(lo, e, 0) 89 | hi, _ = bits.Add64(hi, 0, carry) 90 | hi, _ = bits.Add64(hi, 0, d) 91 | return 92 | } 93 | 94 | func madd2sb(a, b, c, e uint64) (superhi, hi, lo uint64) { 95 | var carry, sum uint64 96 | 97 | hi, lo = bits.Mul64(a, b) 98 | lo, carry = bits.Add64(lo, lo, 0) 99 | hi, superhi = bits.Add64(hi, hi, carry) 100 | 101 | sum, carry = bits.Add64(c, e, 0) 102 | hi, _ = bits.Add64(hi, 0, carry) 103 | lo, carry = bits.Add64(lo, sum, 0) 104 | hi, _ = bits.Add64(hi, 0, carry) 105 | return 106 | } 107 | 108 | func madd1sb(a, b, e uint64) (superhi, hi, lo uint64) { 109 | var carry uint64 110 | 111 | hi, lo = bits.Mul64(a, b) 112 | lo, carry = bits.Add64(lo, lo, 0) 113 | hi, superhi = bits.Add64(hi, hi, carry) 114 | lo, carry = bits.Add64(lo, e, 0) 115 | hi, _ = bits.Add64(hi, 0, carry) 116 | return 117 | } 118 | 119 | func madd3(a, b, c, d, e uint64) (hi uint64, lo uint64) { 120 | var carry uint64 121 | hi, lo = bits.Mul64(a, b) 122 | c, carry = bits.Add64(c, d, 0) 123 | hi, _ = bits.Add64(hi, 0, carry) 124 | lo, carry = bits.Add64(lo, c, 0) 125 | hi, _ = bits.Add64(hi, e, carry) 126 | return 127 | } 128 | -------------------------------------------------------------------------------- /ecc/bn256/fp/element_mul.go: -------------------------------------------------------------------------------- 1 | // +build !amd64 2 | 3 | // Copyright 2020 ConsenSys AG 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | 17 | // Code generated by goff (v0.2.2) DO NOT EDIT 18 | 19 | // Package fp contains field arithmetic operations 20 | package fp 21 | 22 | // /!\ WARNING /!\ 23 | // this code has not been audited and is provided as-is. In particular, 24 | // there is no security guarantees such as constant time implementation 25 | // or side-channel attack resistance 26 | // /!\ WARNING /!\ 27 | 28 | import "math/bits" 29 | 30 | // Mul z = x * y mod q 31 | // see https://hackmd.io/@zkteam/modular_multiplication 32 | func (z *Element) Mul(x, y *Element) *Element { 33 | 34 | var t [4]uint64 35 | var c [3]uint64 36 | { 37 | // round 0 38 | v := x[0] 39 | c[1], c[0] = bits.Mul64(v, y[0]) 40 | m := c[0] * 9786893198990664585 41 | c[2] = madd0(m, 4332616871279656263, c[0]) 42 | c[1], c[0] = madd1(v, y[1], c[1]) 43 | c[2], t[0] = madd2(m, 10917124144477883021, c[2], c[0]) 44 | c[1], c[0] = madd1(v, y[2], c[1]) 45 | c[2], t[1] = madd2(m, 13281191951274694749, c[2], c[0]) 46 | c[1], c[0] = madd1(v, y[3], c[1]) 47 | t[3], t[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) 48 | } 49 | { 50 | // round 1 51 | v := x[1] 52 | c[1], c[0] = madd1(v, y[0], t[0]) 53 | m := c[0] * 9786893198990664585 54 | c[2] = madd0(m, 4332616871279656263, c[0]) 55 | c[1], c[0] = madd2(v, y[1], c[1], t[1]) 56 | c[2], t[0] = madd2(m, 10917124144477883021, c[2], c[0]) 57 | c[1], c[0] = madd2(v, y[2], c[1], t[2]) 58 | c[2], t[1] = madd2(m, 13281191951274694749, c[2], c[0]) 59 | c[1], c[0] = madd2(v, y[3], c[1], t[3]) 60 | t[3], t[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) 61 | } 62 | { 63 | // round 2 64 | v := x[2] 65 | c[1], c[0] = madd1(v, y[0], t[0]) 66 | m := c[0] * 9786893198990664585 67 | c[2] = madd0(m, 4332616871279656263, c[0]) 68 | c[1], c[0] = madd2(v, y[1], c[1], t[1]) 69 | c[2], t[0] = madd2(m, 10917124144477883021, c[2], c[0]) 70 | c[1], c[0] = madd2(v, y[2], c[1], t[2]) 71 | c[2], t[1] = madd2(m, 13281191951274694749, c[2], c[0]) 72 | c[1], c[0] = madd2(v, y[3], c[1], t[3]) 73 | t[3], t[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) 74 | } 75 | { 76 | // round 3 77 | v := x[3] 78 | c[1], c[0] = madd1(v, y[0], t[0]) 79 | m := c[0] * 9786893198990664585 80 | c[2] = madd0(m, 4332616871279656263, c[0]) 81 | c[1], c[0] = madd2(v, y[1], c[1], t[1]) 82 | c[2], z[0] = madd2(m, 10917124144477883021, c[2], c[0]) 83 | c[1], c[0] = madd2(v, y[2], c[1], t[2]) 84 | c[2], z[1] = madd2(m, 13281191951274694749, c[2], c[0]) 85 | c[1], c[0] = madd2(v, y[3], c[1], t[3]) 86 | z[3], z[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) 87 | } 88 | 89 | // if z > q --> z -= q 90 | // note: this is NOT constant time 91 | if !(z[3] < 3486998266802970665 || (z[3] == 3486998266802970665 && (z[2] < 13281191951274694749 || (z[2] == 13281191951274694749 && (z[1] < 10917124144477883021 || (z[1] == 10917124144477883021 && (z[0] < 4332616871279656263))))))) { 92 | var b uint64 93 | z[0], b = bits.Sub64(z[0], 4332616871279656263, 0) 94 | z[1], b = bits.Sub64(z[1], 10917124144477883021, b) 95 | z[2], b = bits.Sub64(z[2], 13281191951274694749, b) 96 | z[3], _ = bits.Sub64(z[3], 3486998266802970665, b) 97 | } 98 | return z 99 | } 100 | 101 | // MulAssign z = z * x mod q 102 | // see https://hackmd.io/@zkteam/modular_multiplication 103 | func (z *Element) MulAssign(x *Element) *Element { 104 | 105 | var t [4]uint64 106 | var c [3]uint64 107 | { 108 | // round 0 109 | v := z[0] 110 | c[1], c[0] = bits.Mul64(v, x[0]) 111 | m := c[0] * 9786893198990664585 112 | c[2] = madd0(m, 4332616871279656263, c[0]) 113 | c[1], c[0] = madd1(v, x[1], c[1]) 114 | c[2], t[0] = madd2(m, 10917124144477883021, c[2], c[0]) 115 | c[1], c[0] = madd1(v, x[2], c[1]) 116 | c[2], t[1] = madd2(m, 13281191951274694749, c[2], c[0]) 117 | c[1], c[0] = madd1(v, x[3], c[1]) 118 | t[3], t[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) 119 | } 120 | { 121 | // round 1 122 | v := z[1] 123 | c[1], c[0] = madd1(v, x[0], t[0]) 124 | m := c[0] * 9786893198990664585 125 | c[2] = madd0(m, 4332616871279656263, c[0]) 126 | c[1], c[0] = madd2(v, x[1], c[1], t[1]) 127 | c[2], t[0] = madd2(m, 10917124144477883021, c[2], c[0]) 128 | c[1], c[0] = madd2(v, x[2], c[1], t[2]) 129 | c[2], t[1] = madd2(m, 13281191951274694749, c[2], c[0]) 130 | c[1], c[0] = madd2(v, x[3], c[1], t[3]) 131 | t[3], t[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) 132 | } 133 | { 134 | // round 2 135 | v := z[2] 136 | c[1], c[0] = madd1(v, x[0], t[0]) 137 | m := c[0] * 9786893198990664585 138 | c[2] = madd0(m, 4332616871279656263, c[0]) 139 | c[1], c[0] = madd2(v, x[1], c[1], t[1]) 140 | c[2], t[0] = madd2(m, 10917124144477883021, c[2], c[0]) 141 | c[1], c[0] = madd2(v, x[2], c[1], t[2]) 142 | c[2], t[1] = madd2(m, 13281191951274694749, c[2], c[0]) 143 | c[1], c[0] = madd2(v, x[3], c[1], t[3]) 144 | t[3], t[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) 145 | } 146 | { 147 | // round 3 148 | v := z[3] 149 | c[1], c[0] = madd1(v, x[0], t[0]) 150 | m := c[0] * 9786893198990664585 151 | c[2] = madd0(m, 4332616871279656263, c[0]) 152 | c[1], c[0] = madd2(v, x[1], c[1], t[1]) 153 | c[2], z[0] = madd2(m, 10917124144477883021, c[2], c[0]) 154 | c[1], c[0] = madd2(v, x[2], c[1], t[2]) 155 | c[2], z[1] = madd2(m, 13281191951274694749, c[2], c[0]) 156 | c[1], c[0] = madd2(v, x[3], c[1], t[3]) 157 | z[3], z[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) 158 | } 159 | 160 | // if z > q --> z -= q 161 | // note: this is NOT constant time 162 | if !(z[3] < 3486998266802970665 || (z[3] == 3486998266802970665 && (z[2] < 13281191951274694749 || (z[2] == 13281191951274694749 && (z[1] < 10917124144477883021 || (z[1] == 10917124144477883021 && (z[0] < 4332616871279656263))))))) { 163 | var b uint64 164 | z[0], b = bits.Sub64(z[0], 4332616871279656263, 0) 165 | z[1], b = bits.Sub64(z[1], 10917124144477883021, b) 166 | z[2], b = bits.Sub64(z[2], 13281191951274694749, b) 167 | z[3], _ = bits.Sub64(z[3], 3486998266802970665, b) 168 | } 169 | return z 170 | } 171 | -------------------------------------------------------------------------------- /ecc/bn256/fp/element_mul_amd64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 ConsenSys AG 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Code generated by goff (v0.2.2) DO NOT EDIT 16 | 17 | // Package fp contains field arithmetic operations 18 | package fp 19 | 20 | // /!\ WARNING /!\ 21 | // this code has not been audited and is provided as-is. In particular, 22 | // there is no security guarantees such as constant time implementation 23 | // or side-channel attack resistance 24 | // /!\ WARNING /!\ 25 | 26 | //go:noescape 27 | func mulAssignElement(res, y *Element) 28 | 29 | //go:noescape 30 | func fromMontElement(res *Element) 31 | 32 | //go:noescape 33 | func reduceElement(res *Element) // for test purposes 34 | 35 | // Mul z = x * y mod q 36 | // see https://hackmd.io/@zkteam/modular_multiplication 37 | func (z *Element) Mul(x, y *Element) *Element { 38 | if z == x { 39 | mulAssignElement(z, y) 40 | return z 41 | } else if z == y { 42 | mulAssignElement(z, x) 43 | return z 44 | } else { 45 | z.Set(x) 46 | mulAssignElement(z, y) 47 | return z 48 | } 49 | } 50 | 51 | // MulAssign z = z * x mod q 52 | // see https://hackmd.io/@zkteam/modular_multiplication 53 | func (z *Element) MulAssign(x *Element) *Element { 54 | mulAssignElement(z, x) 55 | return z 56 | } 57 | -------------------------------------------------------------------------------- /ecc/bn256/fp/element_square.go: -------------------------------------------------------------------------------- 1 | // +build !amd64 2 | 3 | // Copyright 2020 ConsenSys AG 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | 17 | // Code generated by goff (v0.2.2) DO NOT EDIT 18 | 19 | // Package fp contains field arithmetic operations 20 | package fp 21 | 22 | // /!\ WARNING /!\ 23 | // this code has not been audited and is provided as-is. In particular, 24 | // there is no security guarantees such as constant time implementation 25 | // or side-channel attack resistance 26 | // /!\ WARNING /!\ 27 | 28 | import "math/bits" 29 | 30 | // Square z = x * x mod q 31 | // see https://hackmd.io/@zkteam/modular_multiplication 32 | func (z *Element) Square(x *Element) *Element { 33 | 34 | var p [4]uint64 35 | 36 | var u, v uint64 37 | { 38 | // round 0 39 | u, p[0] = bits.Mul64(x[0], x[0]) 40 | m := p[0] * 9786893198990664585 41 | C := madd0(m, 4332616871279656263, p[0]) 42 | var t uint64 43 | t, u, v = madd1sb(x[0], x[1], u) 44 | C, p[0] = madd2(m, 10917124144477883021, v, C) 45 | t, u, v = madd1s(x[0], x[2], t, u) 46 | C, p[1] = madd2(m, 13281191951274694749, v, C) 47 | _, u, v = madd1s(x[0], x[3], t, u) 48 | p[3], p[2] = madd3(m, 3486998266802970665, v, C, u) 49 | } 50 | { 51 | // round 1 52 | m := p[0] * 9786893198990664585 53 | C := madd0(m, 4332616871279656263, p[0]) 54 | u, v = madd1(x[1], x[1], p[1]) 55 | C, p[0] = madd2(m, 10917124144477883021, v, C) 56 | var t uint64 57 | t, u, v = madd2sb(x[1], x[2], p[2], u) 58 | C, p[1] = madd2(m, 13281191951274694749, v, C) 59 | _, u, v = madd2s(x[1], x[3], p[3], t, u) 60 | p[3], p[2] = madd3(m, 3486998266802970665, v, C, u) 61 | } 62 | { 63 | // round 2 64 | m := p[0] * 9786893198990664585 65 | C := madd0(m, 4332616871279656263, p[0]) 66 | C, p[0] = madd2(m, 10917124144477883021, p[1], C) 67 | u, v = madd1(x[2], x[2], p[2]) 68 | C, p[1] = madd2(m, 13281191951274694749, v, C) 69 | _, u, v = madd2sb(x[2], x[3], p[3], u) 70 | p[3], p[2] = madd3(m, 3486998266802970665, v, C, u) 71 | } 72 | { 73 | // round 3 74 | m := p[0] * 9786893198990664585 75 | C := madd0(m, 4332616871279656263, p[0]) 76 | C, z[0] = madd2(m, 10917124144477883021, p[1], C) 77 | C, z[1] = madd2(m, 13281191951274694749, p[2], C) 78 | u, v = madd1(x[3], x[3], p[3]) 79 | z[3], z[2] = madd3(m, 3486998266802970665, v, C, u) 80 | } 81 | 82 | // if z > q --> z -= q 83 | // note: this is NOT constant time 84 | if !(z[3] < 3486998266802970665 || (z[3] == 3486998266802970665 && (z[2] < 13281191951274694749 || (z[2] == 13281191951274694749 && (z[1] < 10917124144477883021 || (z[1] == 10917124144477883021 && (z[0] < 4332616871279656263))))))) { 85 | var b uint64 86 | z[0], b = bits.Sub64(z[0], 4332616871279656263, 0) 87 | z[1], b = bits.Sub64(z[1], 10917124144477883021, b) 88 | z[2], b = bits.Sub64(z[2], 13281191951274694749, b) 89 | z[3], _ = bits.Sub64(z[3], 3486998266802970665, b) 90 | } 91 | return z 92 | 93 | } 94 | -------------------------------------------------------------------------------- /ecc/bn256/fp/element_square_amd64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 ConsenSys AG 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Code generated by goff (v0.2.2) DO NOT EDIT 16 | 17 | // Package fp contains field arithmetic operations 18 | package fp 19 | 20 | // /!\ WARNING /!\ 21 | // this code has not been audited and is provided as-is. In particular, 22 | // there is no security guarantees such as constant time implementation 23 | // or side-channel attack resistance 24 | // /!\ WARNING /!\ 25 | 26 | //go:noescape 27 | func squareElement(res, y *Element) 28 | 29 | // Square z = x * x mod q 30 | // see https://hackmd.io/@zkteam/modular_multiplication 31 | func (z *Element) Square(x *Element) *Element { 32 | squareElement(z, x) 33 | return z 34 | } 35 | -------------------------------------------------------------------------------- /ecc/bn256/fp/element_square_amd64.s: -------------------------------------------------------------------------------- 1 | #include "textflag.h" 2 | // func squareElement(res,y *Element) 3 | TEXT ·squareElement(SB), NOSPLIT, $0-16 4 | // the algorithm is described here 5 | // https://hackmd.io/@zkteam/modular_multiplication 6 | // for i=0 to N-1 7 | // A, t[i] = x[i] * x[i] + t[i] 8 | // p = 0 9 | // for j=i+1 to N-1 10 | // p,A,t[j] = 2*x[j]*x[i] + t[j] + (p,A) 11 | // m = t[0] * q'[0] 12 | // C, _ = t[0] + q[0]*m 13 | // for j=1 to N-1 14 | // C, t[j-1] = q[j]*m + t[j] + C 15 | // t[N-1] = C + A 16 | 17 | // if adx and mulx instructions are not available, uses MUL algorithm. 18 | 19 | CMPB ·supportAdx(SB), $0x0000000000000001 // check if we support MULX and ADOX instructions 20 | JNE no_adx // no support for MULX or ADOX instructions 21 | MOVQ y+8(FP), DI // dereference y 22 | // outter loop 0 23 | XORQ AX, AX // clear up flags 24 | // dx = y[0] 25 | MOVQ 0(DI), DX 26 | MULXQ 8(DI), R9, R10 27 | MULXQ 16(DI), AX, R11 28 | ADCXQ AX, R10 29 | MULXQ 24(DI), AX, R8 30 | ADCXQ AX, R11 31 | MOVQ $0x0000000000000000, AX 32 | ADCXQ AX, R8 33 | XORQ AX, AX // clear up flags 34 | MULXQ DX, CX, DX 35 | ADCXQ R9, R9 36 | MOVQ R9, BX 37 | ADOXQ DX, BX 38 | ADCXQ R10, R10 39 | MOVQ R10, BP 40 | ADOXQ AX, BP 41 | ADCXQ R11, R11 42 | MOVQ R11, SI 43 | ADOXQ AX, SI 44 | ADCXQ R8, R8 45 | ADOXQ AX, R8 46 | MOVQ $0x87d20782e4866389, DX 47 | MULXQ CX, R12, DX 48 | XORQ DX, DX // clear up flags 49 | MOVQ $0x3c208c16d87cfd47, DX 50 | MULXQ R12, AX, DX 51 | ADCXQ CX, AX 52 | MOVQ DX, CX 53 | MOVQ $0x97816a916871ca8d, DX 54 | ADCXQ BX, CX 55 | MULXQ R12, AX, BX 56 | ADOXQ AX, CX 57 | MOVQ $0xb85045b68181585d, DX 58 | ADCXQ BP, BX 59 | MULXQ R12, AX, BP 60 | ADOXQ AX, BX 61 | MOVQ $0x30644e72e131a029, DX 62 | ADCXQ SI, BP 63 | MULXQ R12, AX, SI 64 | ADOXQ AX, BP 65 | MOVQ $0x0000000000000000, AX 66 | ADCXQ AX, SI 67 | ADOXQ R8, SI 68 | // outter loop 1 69 | XORQ AX, AX // clear up flags 70 | // dx = y[1] 71 | MOVQ 8(DI), DX 72 | MULXQ 16(DI), R13, R14 73 | MULXQ 24(DI), AX, R8 74 | ADCXQ AX, R14 75 | MOVQ $0x0000000000000000, AX 76 | ADCXQ AX, R8 77 | XORQ AX, AX // clear up flags 78 | ADCXQ R13, R13 79 | ADOXQ R13, BP 80 | ADCXQ R14, R14 81 | ADOXQ R14, SI 82 | ADCXQ R8, R8 83 | ADOXQ AX, R8 84 | XORQ AX, AX // clear up flags 85 | MULXQ DX, AX, DX 86 | ADOXQ AX, BX 87 | MOVQ $0x0000000000000000, AX 88 | ADOXQ DX, BP 89 | ADOXQ AX, SI 90 | ADOXQ AX, R8 91 | MOVQ $0x87d20782e4866389, DX 92 | MULXQ CX, R15, DX 93 | XORQ DX, DX // clear up flags 94 | MOVQ $0x3c208c16d87cfd47, DX 95 | MULXQ R15, AX, DX 96 | ADCXQ CX, AX 97 | MOVQ DX, CX 98 | MOVQ $0x97816a916871ca8d, DX 99 | ADCXQ BX, CX 100 | MULXQ R15, AX, BX 101 | ADOXQ AX, CX 102 | MOVQ $0xb85045b68181585d, DX 103 | ADCXQ BP, BX 104 | MULXQ R15, AX, BP 105 | ADOXQ AX, BX 106 | MOVQ $0x30644e72e131a029, DX 107 | ADCXQ SI, BP 108 | MULXQ R15, AX, SI 109 | ADOXQ AX, BP 110 | MOVQ $0x0000000000000000, AX 111 | ADCXQ AX, SI 112 | ADOXQ R8, SI 113 | // outter loop 2 114 | XORQ AX, AX // clear up flags 115 | // dx = y[2] 116 | MOVQ 16(DI), DX 117 | MULXQ 24(DI), R9, R8 118 | ADCXQ R9, R9 119 | ADOXQ R9, SI 120 | ADCXQ R8, R8 121 | ADOXQ AX, R8 122 | XORQ AX, AX // clear up flags 123 | MULXQ DX, AX, DX 124 | ADOXQ AX, BP 125 | MOVQ $0x0000000000000000, AX 126 | ADOXQ DX, SI 127 | ADOXQ AX, R8 128 | MOVQ $0x87d20782e4866389, DX 129 | MULXQ CX, R10, DX 130 | XORQ DX, DX // clear up flags 131 | MOVQ $0x3c208c16d87cfd47, DX 132 | MULXQ R10, AX, DX 133 | ADCXQ CX, AX 134 | MOVQ DX, CX 135 | MOVQ $0x97816a916871ca8d, DX 136 | ADCXQ BX, CX 137 | MULXQ R10, AX, BX 138 | ADOXQ AX, CX 139 | MOVQ $0xb85045b68181585d, DX 140 | ADCXQ BP, BX 141 | MULXQ R10, AX, BP 142 | ADOXQ AX, BX 143 | MOVQ $0x30644e72e131a029, DX 144 | ADCXQ SI, BP 145 | MULXQ R10, AX, SI 146 | ADOXQ AX, BP 147 | MOVQ $0x0000000000000000, AX 148 | ADCXQ AX, SI 149 | ADOXQ R8, SI 150 | // outter loop 3 151 | XORQ AX, AX // clear up flags 152 | // dx = y[3] 153 | MOVQ 24(DI), DX 154 | MULXQ DX, AX, R8 155 | ADCXQ AX, SI 156 | MOVQ $0x0000000000000000, AX 157 | ADCXQ AX, R8 158 | MOVQ $0x87d20782e4866389, DX 159 | MULXQ CX, R11, DX 160 | XORQ DX, DX // clear up flags 161 | MOVQ $0x3c208c16d87cfd47, DX 162 | MULXQ R11, AX, DX 163 | ADCXQ CX, AX 164 | MOVQ DX, CX 165 | MOVQ $0x97816a916871ca8d, DX 166 | ADCXQ BX, CX 167 | MULXQ R11, AX, BX 168 | ADOXQ AX, CX 169 | MOVQ $0xb85045b68181585d, DX 170 | ADCXQ BP, BX 171 | MULXQ R11, AX, BP 172 | ADOXQ AX, BX 173 | MOVQ $0x30644e72e131a029, DX 174 | ADCXQ SI, BP 175 | MULXQ R11, AX, SI 176 | ADOXQ AX, BP 177 | MOVQ $0x0000000000000000, AX 178 | ADCXQ AX, SI 179 | ADOXQ R8, SI 180 | // dereference res 181 | MOVQ res+0(FP), R12 182 | reduce: 183 | MOVQ $0x30644e72e131a029, DX 184 | CMPQ SI, DX // note: this is not constant time, comment out to have constant time mul 185 | JCC sub_t_q // t > q 186 | t_is_smaller: 187 | MOVQ CX, 0(R12) 188 | MOVQ BX, 8(R12) 189 | MOVQ BP, 16(R12) 190 | MOVQ SI, 24(R12) 191 | RET 192 | sub_t_q: 193 | MOVQ CX, R13 194 | MOVQ $0x3c208c16d87cfd47, DX 195 | SUBQ DX, R13 196 | MOVQ BX, R14 197 | MOVQ $0x97816a916871ca8d, DX 198 | SBBQ DX, R14 199 | MOVQ BP, R15 200 | MOVQ $0xb85045b68181585d, DX 201 | SBBQ DX, R15 202 | MOVQ SI, R9 203 | MOVQ $0x30644e72e131a029, DX 204 | SBBQ DX, R9 205 | JCS t_is_smaller 206 | MOVQ R13, 0(R12) 207 | MOVQ R14, 8(R12) 208 | MOVQ R15, 16(R12) 209 | MOVQ R9, 24(R12) 210 | RET 211 | no_adx: 212 | // dereference y 213 | MOVQ y+8(FP), R13 214 | MOVQ 0(R13), AX 215 | MOVQ 0(R13), R11 216 | MULQ R11 217 | MOVQ AX, CX 218 | MOVQ DX, DI 219 | MOVQ $0x87d20782e4866389, R8 220 | IMULQ CX, R8 221 | MOVQ $0x3c208c16d87cfd47, AX 222 | MULQ R8 223 | ADDQ CX, AX 224 | ADCQ $0x0000000000000000, DX 225 | MOVQ DX, R10 226 | MOVQ 8(R13), AX 227 | MULQ R11 228 | MOVQ DI, BX 229 | ADDQ AX, BX 230 | ADCQ $0x0000000000000000, DX 231 | MOVQ DX, DI 232 | MOVQ $0x97816a916871ca8d, AX 233 | MULQ R8 234 | ADDQ BX, R10 235 | ADCQ $0x0000000000000000, DX 236 | ADDQ AX, R10 237 | ADCQ $0x0000000000000000, DX 238 | MOVQ R10, CX 239 | MOVQ DX, R10 240 | MOVQ 16(R13), AX 241 | MULQ R11 242 | MOVQ DI, BP 243 | ADDQ AX, BP 244 | ADCQ $0x0000000000000000, DX 245 | MOVQ DX, DI 246 | MOVQ $0xb85045b68181585d, AX 247 | MULQ R8 248 | ADDQ BP, R10 249 | ADCQ $0x0000000000000000, DX 250 | ADDQ AX, R10 251 | ADCQ $0x0000000000000000, DX 252 | MOVQ R10, BX 253 | MOVQ DX, R10 254 | MOVQ 24(R13), AX 255 | MULQ R11 256 | MOVQ DI, SI 257 | ADDQ AX, SI 258 | ADCQ $0x0000000000000000, DX 259 | MOVQ DX, DI 260 | MOVQ $0x30644e72e131a029, AX 261 | MULQ R8 262 | ADDQ SI, R10 263 | ADCQ $0x0000000000000000, DX 264 | ADDQ AX, R10 265 | ADCQ $0x0000000000000000, DX 266 | MOVQ R10, BP 267 | MOVQ DX, R10 268 | ADDQ R10, DI 269 | MOVQ DI, SI 270 | MOVQ 0(R13), AX 271 | MOVQ 8(R13), R11 272 | MULQ R11 273 | ADDQ AX, CX 274 | ADCQ $0x0000000000000000, DX 275 | MOVQ DX, DI 276 | MOVQ $0x87d20782e4866389, R8 277 | IMULQ CX, R8 278 | MOVQ $0x3c208c16d87cfd47, AX 279 | MULQ R8 280 | ADDQ CX, AX 281 | ADCQ $0x0000000000000000, DX 282 | MOVQ DX, R10 283 | MOVQ 8(R13), AX 284 | MULQ R11 285 | ADDQ DI, BX 286 | ADCQ $0x0000000000000000, DX 287 | ADDQ AX, BX 288 | ADCQ $0x0000000000000000, DX 289 | MOVQ DX, DI 290 | MOVQ $0x97816a916871ca8d, AX 291 | MULQ R8 292 | ADDQ BX, R10 293 | ADCQ $0x0000000000000000, DX 294 | ADDQ AX, R10 295 | ADCQ $0x0000000000000000, DX 296 | MOVQ R10, CX 297 | MOVQ DX, R10 298 | MOVQ 16(R13), AX 299 | MULQ R11 300 | ADDQ DI, BP 301 | ADCQ $0x0000000000000000, DX 302 | ADDQ AX, BP 303 | ADCQ $0x0000000000000000, DX 304 | MOVQ DX, DI 305 | MOVQ $0xb85045b68181585d, AX 306 | MULQ R8 307 | ADDQ BP, R10 308 | ADCQ $0x0000000000000000, DX 309 | ADDQ AX, R10 310 | ADCQ $0x0000000000000000, DX 311 | MOVQ R10, BX 312 | MOVQ DX, R10 313 | MOVQ 24(R13), AX 314 | MULQ R11 315 | ADDQ DI, SI 316 | ADCQ $0x0000000000000000, DX 317 | ADDQ AX, SI 318 | ADCQ $0x0000000000000000, DX 319 | MOVQ DX, DI 320 | MOVQ $0x30644e72e131a029, AX 321 | MULQ R8 322 | ADDQ SI, R10 323 | ADCQ $0x0000000000000000, DX 324 | ADDQ AX, R10 325 | ADCQ $0x0000000000000000, DX 326 | MOVQ R10, BP 327 | MOVQ DX, R10 328 | ADDQ R10, DI 329 | MOVQ DI, SI 330 | MOVQ 0(R13), AX 331 | MOVQ 16(R13), R11 332 | MULQ R11 333 | ADDQ AX, CX 334 | ADCQ $0x0000000000000000, DX 335 | MOVQ DX, DI 336 | MOVQ $0x87d20782e4866389, R8 337 | IMULQ CX, R8 338 | MOVQ $0x3c208c16d87cfd47, AX 339 | MULQ R8 340 | ADDQ CX, AX 341 | ADCQ $0x0000000000000000, DX 342 | MOVQ DX, R10 343 | MOVQ 8(R13), AX 344 | MULQ R11 345 | ADDQ DI, BX 346 | ADCQ $0x0000000000000000, DX 347 | ADDQ AX, BX 348 | ADCQ $0x0000000000000000, DX 349 | MOVQ DX, DI 350 | MOVQ $0x97816a916871ca8d, AX 351 | MULQ R8 352 | ADDQ BX, R10 353 | ADCQ $0x0000000000000000, DX 354 | ADDQ AX, R10 355 | ADCQ $0x0000000000000000, DX 356 | MOVQ R10, CX 357 | MOVQ DX, R10 358 | MOVQ 16(R13), AX 359 | MULQ R11 360 | ADDQ DI, BP 361 | ADCQ $0x0000000000000000, DX 362 | ADDQ AX, BP 363 | ADCQ $0x0000000000000000, DX 364 | MOVQ DX, DI 365 | MOVQ $0xb85045b68181585d, AX 366 | MULQ R8 367 | ADDQ BP, R10 368 | ADCQ $0x0000000000000000, DX 369 | ADDQ AX, R10 370 | ADCQ $0x0000000000000000, DX 371 | MOVQ R10, BX 372 | MOVQ DX, R10 373 | MOVQ 24(R13), AX 374 | MULQ R11 375 | ADDQ DI, SI 376 | ADCQ $0x0000000000000000, DX 377 | ADDQ AX, SI 378 | ADCQ $0x0000000000000000, DX 379 | MOVQ DX, DI 380 | MOVQ $0x30644e72e131a029, AX 381 | MULQ R8 382 | ADDQ SI, R10 383 | ADCQ $0x0000000000000000, DX 384 | ADDQ AX, R10 385 | ADCQ $0x0000000000000000, DX 386 | MOVQ R10, BP 387 | MOVQ DX, R10 388 | ADDQ R10, DI 389 | MOVQ DI, SI 390 | MOVQ 0(R13), AX 391 | MOVQ 24(R13), R11 392 | MULQ R11 393 | ADDQ AX, CX 394 | ADCQ $0x0000000000000000, DX 395 | MOVQ DX, DI 396 | MOVQ $0x87d20782e4866389, R8 397 | IMULQ CX, R8 398 | MOVQ $0x3c208c16d87cfd47, AX 399 | MULQ R8 400 | ADDQ CX, AX 401 | ADCQ $0x0000000000000000, DX 402 | MOVQ DX, R10 403 | MOVQ 8(R13), AX 404 | MULQ R11 405 | ADDQ DI, BX 406 | ADCQ $0x0000000000000000, DX 407 | ADDQ AX, BX 408 | ADCQ $0x0000000000000000, DX 409 | MOVQ DX, DI 410 | MOVQ $0x97816a916871ca8d, AX 411 | MULQ R8 412 | ADDQ BX, R10 413 | ADCQ $0x0000000000000000, DX 414 | ADDQ AX, R10 415 | ADCQ $0x0000000000000000, DX 416 | MOVQ R10, CX 417 | MOVQ DX, R10 418 | MOVQ 16(R13), AX 419 | MULQ R11 420 | ADDQ DI, BP 421 | ADCQ $0x0000000000000000, DX 422 | ADDQ AX, BP 423 | ADCQ $0x0000000000000000, DX 424 | MOVQ DX, DI 425 | MOVQ $0xb85045b68181585d, AX 426 | MULQ R8 427 | ADDQ BP, R10 428 | ADCQ $0x0000000000000000, DX 429 | ADDQ AX, R10 430 | ADCQ $0x0000000000000000, DX 431 | MOVQ R10, BX 432 | MOVQ DX, R10 433 | MOVQ 24(R13), AX 434 | MULQ R11 435 | ADDQ DI, SI 436 | ADCQ $0x0000000000000000, DX 437 | ADDQ AX, SI 438 | ADCQ $0x0000000000000000, DX 439 | MOVQ DX, DI 440 | MOVQ $0x30644e72e131a029, AX 441 | MULQ R8 442 | ADDQ SI, R10 443 | ADCQ $0x0000000000000000, DX 444 | ADDQ AX, R10 445 | ADCQ $0x0000000000000000, DX 446 | MOVQ R10, BP 447 | MOVQ DX, R10 448 | ADDQ R10, DI 449 | MOVQ DI, SI 450 | // dereference res 451 | MOVQ res+0(FP), R12 452 | JMP reduce 453 | -------------------------------------------------------------------------------- /ecc/bn256/fr/arith.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 ConsenSys AG 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Code generated by goff (v0.2.2) DO NOT EDIT 16 | 17 | // Package fr contains field arithmetic operations 18 | package fr 19 | 20 | import ( 21 | "math/bits" 22 | 23 | "golang.org/x/sys/cpu" 24 | ) 25 | 26 | var supportAdx = cpu.X86.HasADX && cpu.X86.HasBMI2 27 | 28 | func madd(a, b, t, u, v uint64) (uint64, uint64, uint64) { 29 | var carry uint64 30 | hi, lo := bits.Mul64(a, b) 31 | v, carry = bits.Add64(lo, v, 0) 32 | u, carry = bits.Add64(hi, u, carry) 33 | t, _ = bits.Add64(t, 0, carry) 34 | return t, u, v 35 | } 36 | 37 | // madd0 hi = a*b + c (discards lo bits) 38 | func madd0(a, b, c uint64) (hi uint64) { 39 | var carry, lo uint64 40 | hi, lo = bits.Mul64(a, b) 41 | _, carry = bits.Add64(lo, c, 0) 42 | hi, _ = bits.Add64(hi, 0, carry) 43 | return 44 | } 45 | 46 | // madd1 hi, lo = a*b + c 47 | func madd1(a, b, c uint64) (hi uint64, lo uint64) { 48 | var carry uint64 49 | hi, lo = bits.Mul64(a, b) 50 | lo, carry = bits.Add64(lo, c, 0) 51 | hi, _ = bits.Add64(hi, 0, carry) 52 | return 53 | } 54 | 55 | // madd2 hi, lo = a*b + c + d 56 | func madd2(a, b, c, d uint64) (hi uint64, lo uint64) { 57 | var carry uint64 58 | hi, lo = bits.Mul64(a, b) 59 | c, carry = bits.Add64(c, d, 0) 60 | hi, _ = bits.Add64(hi, 0, carry) 61 | lo, carry = bits.Add64(lo, c, 0) 62 | hi, _ = bits.Add64(hi, 0, carry) 63 | return 64 | } 65 | 66 | // madd2s superhi, hi, lo = 2*a*b + c + d + e 67 | func madd2s(a, b, c, d, e uint64) (superhi, hi, lo uint64) { 68 | var carry, sum uint64 69 | 70 | hi, lo = bits.Mul64(a, b) 71 | lo, carry = bits.Add64(lo, lo, 0) 72 | hi, superhi = bits.Add64(hi, hi, carry) 73 | 74 | sum, carry = bits.Add64(c, e, 0) 75 | hi, _ = bits.Add64(hi, 0, carry) 76 | lo, carry = bits.Add64(lo, sum, 0) 77 | hi, _ = bits.Add64(hi, 0, carry) 78 | hi, _ = bits.Add64(hi, 0, d) 79 | return 80 | } 81 | 82 | func madd1s(a, b, d, e uint64) (superhi, hi, lo uint64) { 83 | var carry uint64 84 | 85 | hi, lo = bits.Mul64(a, b) 86 | lo, carry = bits.Add64(lo, lo, 0) 87 | hi, superhi = bits.Add64(hi, hi, carry) 88 | lo, carry = bits.Add64(lo, e, 0) 89 | hi, _ = bits.Add64(hi, 0, carry) 90 | hi, _ = bits.Add64(hi, 0, d) 91 | return 92 | } 93 | 94 | func madd2sb(a, b, c, e uint64) (superhi, hi, lo uint64) { 95 | var carry, sum uint64 96 | 97 | hi, lo = bits.Mul64(a, b) 98 | lo, carry = bits.Add64(lo, lo, 0) 99 | hi, superhi = bits.Add64(hi, hi, carry) 100 | 101 | sum, carry = bits.Add64(c, e, 0) 102 | hi, _ = bits.Add64(hi, 0, carry) 103 | lo, carry = bits.Add64(lo, sum, 0) 104 | hi, _ = bits.Add64(hi, 0, carry) 105 | return 106 | } 107 | 108 | func madd1sb(a, b, e uint64) (superhi, hi, lo uint64) { 109 | var carry uint64 110 | 111 | hi, lo = bits.Mul64(a, b) 112 | lo, carry = bits.Add64(lo, lo, 0) 113 | hi, superhi = bits.Add64(hi, hi, carry) 114 | lo, carry = bits.Add64(lo, e, 0) 115 | hi, _ = bits.Add64(hi, 0, carry) 116 | return 117 | } 118 | 119 | func madd3(a, b, c, d, e uint64) (hi uint64, lo uint64) { 120 | var carry uint64 121 | hi, lo = bits.Mul64(a, b) 122 | c, carry = bits.Add64(c, d, 0) 123 | hi, _ = bits.Add64(hi, 0, carry) 124 | lo, carry = bits.Add64(lo, c, 0) 125 | hi, _ = bits.Add64(hi, e, carry) 126 | return 127 | } 128 | -------------------------------------------------------------------------------- /ecc/bn256/fr/element_mul.go: -------------------------------------------------------------------------------- 1 | // +build !amd64 2 | 3 | // Copyright 2020 ConsenSys AG 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | 17 | // Code generated by goff (v0.2.2) DO NOT EDIT 18 | 19 | // Package fr contains field arithmetic operations 20 | package fr 21 | 22 | // /!\ WARNING /!\ 23 | // this code has not been audited and is provided as-is. In particular, 24 | // there is no security guarantees such as constant time implementation 25 | // or side-channel attack resistance 26 | // /!\ WARNING /!\ 27 | 28 | import "math/bits" 29 | 30 | // Mul z = x * y mod q 31 | // see https://hackmd.io/@zkteam/modular_multiplication 32 | func (z *Element) Mul(x, y *Element) *Element { 33 | 34 | var t [4]uint64 35 | var c [3]uint64 36 | { 37 | // round 0 38 | v := x[0] 39 | c[1], c[0] = bits.Mul64(v, y[0]) 40 | m := c[0] * 14042775128853446655 41 | c[2] = madd0(m, 4891460686036598785, c[0]) 42 | c[1], c[0] = madd1(v, y[1], c[1]) 43 | c[2], t[0] = madd2(m, 2896914383306846353, c[2], c[0]) 44 | c[1], c[0] = madd1(v, y[2], c[1]) 45 | c[2], t[1] = madd2(m, 13281191951274694749, c[2], c[0]) 46 | c[1], c[0] = madd1(v, y[3], c[1]) 47 | t[3], t[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) 48 | } 49 | { 50 | // round 1 51 | v := x[1] 52 | c[1], c[0] = madd1(v, y[0], t[0]) 53 | m := c[0] * 14042775128853446655 54 | c[2] = madd0(m, 4891460686036598785, c[0]) 55 | c[1], c[0] = madd2(v, y[1], c[1], t[1]) 56 | c[2], t[0] = madd2(m, 2896914383306846353, c[2], c[0]) 57 | c[1], c[0] = madd2(v, y[2], c[1], t[2]) 58 | c[2], t[1] = madd2(m, 13281191951274694749, c[2], c[0]) 59 | c[1], c[0] = madd2(v, y[3], c[1], t[3]) 60 | t[3], t[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) 61 | } 62 | { 63 | // round 2 64 | v := x[2] 65 | c[1], c[0] = madd1(v, y[0], t[0]) 66 | m := c[0] * 14042775128853446655 67 | c[2] = madd0(m, 4891460686036598785, c[0]) 68 | c[1], c[0] = madd2(v, y[1], c[1], t[1]) 69 | c[2], t[0] = madd2(m, 2896914383306846353, c[2], c[0]) 70 | c[1], c[0] = madd2(v, y[2], c[1], t[2]) 71 | c[2], t[1] = madd2(m, 13281191951274694749, c[2], c[0]) 72 | c[1], c[0] = madd2(v, y[3], c[1], t[3]) 73 | t[3], t[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) 74 | } 75 | { 76 | // round 3 77 | v := x[3] 78 | c[1], c[0] = madd1(v, y[0], t[0]) 79 | m := c[0] * 14042775128853446655 80 | c[2] = madd0(m, 4891460686036598785, c[0]) 81 | c[1], c[0] = madd2(v, y[1], c[1], t[1]) 82 | c[2], z[0] = madd2(m, 2896914383306846353, c[2], c[0]) 83 | c[1], c[0] = madd2(v, y[2], c[1], t[2]) 84 | c[2], z[1] = madd2(m, 13281191951274694749, c[2], c[0]) 85 | c[1], c[0] = madd2(v, y[3], c[1], t[3]) 86 | z[3], z[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) 87 | } 88 | 89 | // if z > q --> z -= q 90 | // note: this is NOT constant time 91 | if !(z[3] < 3486998266802970665 || (z[3] == 3486998266802970665 && (z[2] < 13281191951274694749 || (z[2] == 13281191951274694749 && (z[1] < 2896914383306846353 || (z[1] == 2896914383306846353 && (z[0] < 4891460686036598785))))))) { 92 | var b uint64 93 | z[0], b = bits.Sub64(z[0], 4891460686036598785, 0) 94 | z[1], b = bits.Sub64(z[1], 2896914383306846353, b) 95 | z[2], b = bits.Sub64(z[2], 13281191951274694749, b) 96 | z[3], _ = bits.Sub64(z[3], 3486998266802970665, b) 97 | } 98 | return z 99 | } 100 | 101 | // MulAssign z = z * x mod q 102 | // see https://hackmd.io/@zkteam/modular_multiplication 103 | func (z *Element) MulAssign(x *Element) *Element { 104 | 105 | var t [4]uint64 106 | var c [3]uint64 107 | { 108 | // round 0 109 | v := z[0] 110 | c[1], c[0] = bits.Mul64(v, x[0]) 111 | m := c[0] * 14042775128853446655 112 | c[2] = madd0(m, 4891460686036598785, c[0]) 113 | c[1], c[0] = madd1(v, x[1], c[1]) 114 | c[2], t[0] = madd2(m, 2896914383306846353, c[2], c[0]) 115 | c[1], c[0] = madd1(v, x[2], c[1]) 116 | c[2], t[1] = madd2(m, 13281191951274694749, c[2], c[0]) 117 | c[1], c[0] = madd1(v, x[3], c[1]) 118 | t[3], t[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) 119 | } 120 | { 121 | // round 1 122 | v := z[1] 123 | c[1], c[0] = madd1(v, x[0], t[0]) 124 | m := c[0] * 14042775128853446655 125 | c[2] = madd0(m, 4891460686036598785, c[0]) 126 | c[1], c[0] = madd2(v, x[1], c[1], t[1]) 127 | c[2], t[0] = madd2(m, 2896914383306846353, c[2], c[0]) 128 | c[1], c[0] = madd2(v, x[2], c[1], t[2]) 129 | c[2], t[1] = madd2(m, 13281191951274694749, c[2], c[0]) 130 | c[1], c[0] = madd2(v, x[3], c[1], t[3]) 131 | t[3], t[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) 132 | } 133 | { 134 | // round 2 135 | v := z[2] 136 | c[1], c[0] = madd1(v, x[0], t[0]) 137 | m := c[0] * 14042775128853446655 138 | c[2] = madd0(m, 4891460686036598785, c[0]) 139 | c[1], c[0] = madd2(v, x[1], c[1], t[1]) 140 | c[2], t[0] = madd2(m, 2896914383306846353, c[2], c[0]) 141 | c[1], c[0] = madd2(v, x[2], c[1], t[2]) 142 | c[2], t[1] = madd2(m, 13281191951274694749, c[2], c[0]) 143 | c[1], c[0] = madd2(v, x[3], c[1], t[3]) 144 | t[3], t[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) 145 | } 146 | { 147 | // round 3 148 | v := z[3] 149 | c[1], c[0] = madd1(v, x[0], t[0]) 150 | m := c[0] * 14042775128853446655 151 | c[2] = madd0(m, 4891460686036598785, c[0]) 152 | c[1], c[0] = madd2(v, x[1], c[1], t[1]) 153 | c[2], z[0] = madd2(m, 2896914383306846353, c[2], c[0]) 154 | c[1], c[0] = madd2(v, x[2], c[1], t[2]) 155 | c[2], z[1] = madd2(m, 13281191951274694749, c[2], c[0]) 156 | c[1], c[0] = madd2(v, x[3], c[1], t[3]) 157 | z[3], z[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) 158 | } 159 | 160 | // if z > q --> z -= q 161 | // note: this is NOT constant time 162 | if !(z[3] < 3486998266802970665 || (z[3] == 3486998266802970665 && (z[2] < 13281191951274694749 || (z[2] == 13281191951274694749 && (z[1] < 2896914383306846353 || (z[1] == 2896914383306846353 && (z[0] < 4891460686036598785))))))) { 163 | var b uint64 164 | z[0], b = bits.Sub64(z[0], 4891460686036598785, 0) 165 | z[1], b = bits.Sub64(z[1], 2896914383306846353, b) 166 | z[2], b = bits.Sub64(z[2], 13281191951274694749, b) 167 | z[3], _ = bits.Sub64(z[3], 3486998266802970665, b) 168 | } 169 | return z 170 | } 171 | -------------------------------------------------------------------------------- /ecc/bn256/fr/element_mul_amd64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 ConsenSys AG 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Code generated by goff (v0.2.2) DO NOT EDIT 16 | 17 | // Package fr contains field arithmetic operations 18 | package fr 19 | 20 | // /!\ WARNING /!\ 21 | // this code has not been audited and is provided as-is. In particular, 22 | // there is no security guarantees such as constant time implementation 23 | // or side-channel attack resistance 24 | // /!\ WARNING /!\ 25 | 26 | //go:noescape 27 | func mulAssignElement(res, y *Element) 28 | 29 | //go:noescape 30 | func fromMontElement(res *Element) 31 | 32 | //go:noescape 33 | func reduceElement(res *Element) // for test purposes 34 | 35 | // Mul z = x * y mod q 36 | // see https://hackmd.io/@zkteam/modular_multiplication 37 | func (z *Element) Mul(x, y *Element) *Element { 38 | if z == x { 39 | mulAssignElement(z, y) 40 | return z 41 | } else if z == y { 42 | mulAssignElement(z, x) 43 | return z 44 | } else { 45 | z.Set(x) 46 | mulAssignElement(z, y) 47 | return z 48 | } 49 | } 50 | 51 | // MulAssign z = z * x mod q 52 | // see https://hackmd.io/@zkteam/modular_multiplication 53 | func (z *Element) MulAssign(x *Element) *Element { 54 | mulAssignElement(z, x) 55 | return z 56 | } 57 | -------------------------------------------------------------------------------- /ecc/bn256/fr/element_square.go: -------------------------------------------------------------------------------- 1 | // +build !amd64 2 | 3 | // Copyright 2020 ConsenSys AG 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | 17 | // Code generated by goff (v0.2.2) DO NOT EDIT 18 | 19 | // Package fr contains field arithmetic operations 20 | package fr 21 | 22 | // /!\ WARNING /!\ 23 | // this code has not been audited and is provided as-is. In particular, 24 | // there is no security guarantees such as constant time implementation 25 | // or side-channel attack resistance 26 | // /!\ WARNING /!\ 27 | 28 | import "math/bits" 29 | 30 | // Square z = x * x mod q 31 | // see https://hackmd.io/@zkteam/modular_multiplication 32 | func (z *Element) Square(x *Element) *Element { 33 | 34 | var p [4]uint64 35 | 36 | var u, v uint64 37 | { 38 | // round 0 39 | u, p[0] = bits.Mul64(x[0], x[0]) 40 | m := p[0] * 14042775128853446655 41 | C := madd0(m, 4891460686036598785, p[0]) 42 | var t uint64 43 | t, u, v = madd1sb(x[0], x[1], u) 44 | C, p[0] = madd2(m, 2896914383306846353, v, C) 45 | t, u, v = madd1s(x[0], x[2], t, u) 46 | C, p[1] = madd2(m, 13281191951274694749, v, C) 47 | _, u, v = madd1s(x[0], x[3], t, u) 48 | p[3], p[2] = madd3(m, 3486998266802970665, v, C, u) 49 | } 50 | { 51 | // round 1 52 | m := p[0] * 14042775128853446655 53 | C := madd0(m, 4891460686036598785, p[0]) 54 | u, v = madd1(x[1], x[1], p[1]) 55 | C, p[0] = madd2(m, 2896914383306846353, v, C) 56 | var t uint64 57 | t, u, v = madd2sb(x[1], x[2], p[2], u) 58 | C, p[1] = madd2(m, 13281191951274694749, v, C) 59 | _, u, v = madd2s(x[1], x[3], p[3], t, u) 60 | p[3], p[2] = madd3(m, 3486998266802970665, v, C, u) 61 | } 62 | { 63 | // round 2 64 | m := p[0] * 14042775128853446655 65 | C := madd0(m, 4891460686036598785, p[0]) 66 | C, p[0] = madd2(m, 2896914383306846353, p[1], C) 67 | u, v = madd1(x[2], x[2], p[2]) 68 | C, p[1] = madd2(m, 13281191951274694749, v, C) 69 | _, u, v = madd2sb(x[2], x[3], p[3], u) 70 | p[3], p[2] = madd3(m, 3486998266802970665, v, C, u) 71 | } 72 | { 73 | // round 3 74 | m := p[0] * 14042775128853446655 75 | C := madd0(m, 4891460686036598785, p[0]) 76 | C, z[0] = madd2(m, 2896914383306846353, p[1], C) 77 | C, z[1] = madd2(m, 13281191951274694749, p[2], C) 78 | u, v = madd1(x[3], x[3], p[3]) 79 | z[3], z[2] = madd3(m, 3486998266802970665, v, C, u) 80 | } 81 | 82 | // if z > q --> z -= q 83 | // note: this is NOT constant time 84 | if !(z[3] < 3486998266802970665 || (z[3] == 3486998266802970665 && (z[2] < 13281191951274694749 || (z[2] == 13281191951274694749 && (z[1] < 2896914383306846353 || (z[1] == 2896914383306846353 && (z[0] < 4891460686036598785))))))) { 85 | var b uint64 86 | z[0], b = bits.Sub64(z[0], 4891460686036598785, 0) 87 | z[1], b = bits.Sub64(z[1], 2896914383306846353, b) 88 | z[2], b = bits.Sub64(z[2], 13281191951274694749, b) 89 | z[3], _ = bits.Sub64(z[3], 3486998266802970665, b) 90 | } 91 | return z 92 | 93 | } 94 | -------------------------------------------------------------------------------- /ecc/bn256/fr/element_square_amd64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 ConsenSys AG 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Code generated by goff (v0.2.2) DO NOT EDIT 16 | 17 | // Package fr contains field arithmetic operations 18 | package fr 19 | 20 | // /!\ WARNING /!\ 21 | // this code has not been audited and is provided as-is. In particular, 22 | // there is no security guarantees such as constant time implementation 23 | // or side-channel attack resistance 24 | // /!\ WARNING /!\ 25 | 26 | //go:noescape 27 | func squareElement(res, y *Element) 28 | 29 | // Square z = x * x mod q 30 | // see https://hackmd.io/@zkteam/modular_multiplication 31 | func (z *Element) Square(x *Element) *Element { 32 | squareElement(z, x) 33 | return z 34 | } 35 | -------------------------------------------------------------------------------- /ecc/bn256/pairing.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 ConsenSys AG 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Code generated by gurvy/internal/generators DO NOT EDIT 16 | 17 | package bn256 18 | 19 | // FinalExponentiation computes the final expo x**(p**6-1)(p**2+1)(p**4 - p**2 +1)/r 20 | func (curve *Curve) FinalExponentiation(z *e12, _z ...*e12) e12 { 21 | var result e12 22 | result.Set(z) 23 | 24 | // if additional parameters are provided, multiply them into z 25 | for _, e := range _z { 26 | result.Mul(&result, e) 27 | } 28 | 29 | result.FinalExponentiation(&result) 30 | 31 | return result 32 | } 33 | 34 | // MillerLoop Miller loop 35 | func (curve *Curve) MillerLoop(P G1Affine, Q G2Affine, result *e12) *e12 { 36 | 37 | // init result 38 | result.SetOne() 39 | 40 | if P.IsInfinity() || Q.IsInfinity() { 41 | return result 42 | } 43 | 44 | // the line goes through QCur and QNext 45 | var QCur, QNext, QNextNeg G2Jac 46 | var QNeg G2Affine 47 | 48 | // Stores -Q 49 | QNeg.Neg(&Q) 50 | 51 | // init QCur with Q 52 | Q.ToJacobian(&QCur) 53 | 54 | var lEval lineEvalRes 55 | 56 | // Miller loop 57 | for i := len(curve.loopCounter) - 2; i >= 0; i-- { 58 | QNext.Set(&QCur) 59 | QNext.Double() 60 | QNextNeg.Neg(&QNext) 61 | 62 | result.Square(result) 63 | 64 | // evaluates line though Qcur,2Qcur at P 65 | lineEvalJac(QCur, QNextNeg, &P, &lEval) 66 | lEval.mulAssign(result) 67 | 68 | if curve.loopCounter[i] == 1 { 69 | // evaluates line through 2Qcur, Q at P 70 | lineEvalAffine(QNext, Q, &P, &lEval) 71 | lEval.mulAssign(result) 72 | 73 | QNext.AddMixed(&Q) 74 | 75 | } else if curve.loopCounter[i] == -1 { 76 | // evaluates line through 2Qcur, -Q at P 77 | lineEvalAffine(QNext, QNeg, &P, &lEval) 78 | lEval.mulAssign(result) 79 | 80 | QNext.AddMixed(&QNeg) 81 | } 82 | QCur.Set(&QNext) 83 | } 84 | 85 | // cf https://eprint.iacr.org/2010/354.pdf for instance for optimal Ate Pairing 86 | var Q1, Q2 G2Affine 87 | 88 | //Q1 = Frob(Q) 89 | Q1.X.Conjugate(&Q.X).MulByNonResiduePower2(&Q1.X) 90 | Q1.Y.Conjugate(&Q.Y).MulByNonResiduePower3(&Q1.Y) 91 | 92 | // Q2 = -Frob2(Q) 93 | Q2.X.MulByNonResiduePowerSquare2(&Q.X) 94 | Q2.Y.MulByNonResiduePowerSquare3(&Q.Y).Neg(&Q2.Y) 95 | 96 | lineEvalAffine(QCur, Q1, &P, &lEval) 97 | lEval.mulAssign(result) 98 | 99 | QCur.AddMixed(&Q1) 100 | 101 | lineEvalAffine(QCur, Q2, &P, &lEval) 102 | lEval.mulAssign(result) 103 | 104 | return result 105 | } 106 | 107 | // lineEval computes the evaluation of the line through Q, R (on the twist) at P 108 | // Q, R are in jacobian coordinates 109 | // The case in which Q=R=Infinity is not handled as this doesn't happen in the SNARK pairing 110 | func lineEvalJac(Q, R G2Jac, P *G1Affine, result *lineEvalRes) { 111 | // converts Q and R to projective coords 112 | Q.ToProjFromJac() 113 | R.ToProjFromJac() 114 | 115 | // line eq: w^3*(QyRz-QzRy)x + w^2*(QzRx - QxRz)y + w^5*(QxRy-QyRxz) 116 | // result.r1 = QyRz-QzRy 117 | // result.r0 = QzRx - QxRz 118 | // result.r2 = QxRy-QyRxz 119 | 120 | result.r1.Mul(&Q.Y, &R.Z) 121 | result.r0.Mul(&Q.Z, &R.X) 122 | result.r2.Mul(&Q.X, &R.Y) 123 | 124 | Q.Z.Mul(&Q.Z, &R.Y) 125 | Q.X.Mul(&Q.X, &R.Z) 126 | Q.Y.Mul(&Q.Y, &R.X) 127 | 128 | result.r1.Sub(&result.r1, &Q.Z) 129 | result.r0.Sub(&result.r0, &Q.X) 130 | result.r2.Sub(&result.r2, &Q.Y) 131 | 132 | // multiply P.Z by coeffs[2] in case P is infinity 133 | result.r1.MulByElement(&result.r1, &P.X) 134 | result.r0.MulByElement(&result.r0, &P.Y) 135 | //result.r2.MulByElement(&result.r2, &P.Z) 136 | } 137 | 138 | // Same as above but R is in affine coords 139 | func lineEvalAffine(Q G2Jac, R G2Affine, P *G1Affine, result *lineEvalRes) { 140 | 141 | // converts Q and R to projective coords 142 | Q.ToProjFromJac() 143 | 144 | // line eq: w^3*(QyRz-QzRy)x + w^2*(QzRx - QxRz)y + w^5*(QxRy-QyRxz) 145 | // result.r1 = QyRz-QzRy 146 | // result.r0 = QzRx - QxRz 147 | // result.r2 = QxRy-QyRxz 148 | 149 | result.r1.Set(&Q.Y) 150 | result.r0.Mul(&Q.Z, &R.X) 151 | result.r2.Mul(&Q.X, &R.Y) 152 | 153 | Q.Z.Mul(&Q.Z, &R.Y) 154 | Q.Y.Mul(&Q.Y, &R.X) 155 | 156 | result.r1.Sub(&result.r1, &Q.Z) 157 | result.r0.Sub(&result.r0, &Q.X) 158 | result.r2.Sub(&result.r2, &Q.Y) 159 | 160 | // multiply P.Z by coeffs[2] in case P is infinity 161 | result.r1.MulByElement(&result.r1, &P.X) 162 | result.r0.MulByElement(&result.r0, &P.Y) 163 | // result.r2.MulByElement(&result.r2, &P.Z) 164 | } 165 | 166 | type lineEvalRes struct { 167 | r0 e2 // c0.b1 168 | r1 e2 // c1.b1 169 | r2 e2 // c1.b2 170 | } 171 | 172 | func (l *lineEvalRes) mulAssign(z *e12) *e12 { 173 | 174 | var a, b, c e12 175 | a.MulByVW(z, &l.r1) 176 | b.MulByV(z, &l.r0) 177 | c.MulByV2W(z, &l.r2) 178 | z.Add(&a, &b).Add(z, &c) 179 | 180 | return z 181 | } 182 | -------------------------------------------------------------------------------- /ecc/bn256/twistededwards/point.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 ConsenSys 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package twistededwards 18 | 19 | import ( 20 | "math/bits" 21 | 22 | "github.com/consensys/gurvy/bn256/fr" 23 | ) 24 | 25 | // Point point on a twisted Edwards curve 26 | type Point struct { 27 | X, Y fr.Element 28 | } 29 | 30 | // PointProj point in projective coordinates 31 | type PointProj struct { 32 | X, Y, Z fr.Element 33 | } 34 | 35 | // Set sets p to p1 and return it 36 | func (p *PointProj) Set(p1 *PointProj) *PointProj { 37 | p.X.Set(&p1.X) 38 | p.Y.Set(&p1.Y) 39 | p.Z.Set(&p1.Z) 40 | return p 41 | } 42 | 43 | // NewPoint creates a new instance of Point 44 | func NewPoint(x, y fr.Element) Point { 45 | return Point{x, y} 46 | } 47 | 48 | // IsOnCurve checks if a point is on the twisted Edwards curve 49 | func (p *Point) IsOnCurve() bool { 50 | 51 | ecurve := GetEdwardsCurve() 52 | 53 | var lhs, rhs, tmp fr.Element 54 | 55 | tmp.Mul(&p.Y, &p.Y) 56 | lhs.Mul(&p.X, &p.X). 57 | Mul(&lhs, &ecurve.A). 58 | Add(&lhs, &tmp) 59 | 60 | tmp.Mul(&p.X, &p.X). 61 | Mul(&tmp, &p.Y). 62 | Mul(&tmp, &p.Y). 63 | Mul(&tmp, &ecurve.D) 64 | rhs.SetOne().Add(&rhs, &tmp) 65 | 66 | // TODO why do we not compare lhs and rhs directly? 67 | lhsreg := lhs.ToRegular() 68 | rhsreg := rhs.ToRegular() 69 | 70 | return rhsreg.Equal(&lhsreg) 71 | } 72 | 73 | // Add adds two points (x,y), (u,v) on a twisted Edwards curve with parameters a, d 74 | // modifies p 75 | func (p *Point) Add(p1, p2 *Point) *Point { 76 | 77 | ecurve := GetEdwardsCurve() 78 | 79 | var xu, yv, xv, yu, dxyuv, one, denx, deny fr.Element 80 | pRes := new(Point) 81 | xv.Mul(&p1.X, &p2.Y) 82 | yu.Mul(&p1.Y, &p2.X) 83 | pRes.X.Add(&xv, &yu) 84 | 85 | xu.Mul(&p1.X, &p2.X).Mul(&xu, &ecurve.A) 86 | yv.Mul(&p1.Y, &p2.Y) 87 | pRes.Y.Sub(&yv, &xu) 88 | 89 | dxyuv.Mul(&xv, &yu).Mul(&dxyuv, &ecurve.D) 90 | one.SetOne() 91 | denx.Add(&one, &dxyuv) 92 | deny.Sub(&one, &dxyuv) 93 | 94 | p.X.Div(&pRes.X, &denx) 95 | p.Y.Div(&pRes.Y, &deny) 96 | 97 | return p 98 | } 99 | 100 | // Double doubles point (x,y) on a twisted Edwards curve with parameters a, d 101 | // modifies p 102 | func (p *Point) Double(p1 *Point) *Point { 103 | p.Add(p1, p1) 104 | return p 105 | } 106 | 107 | // FromProj sets p in affine from p in projective 108 | func (p *Point) FromProj(p1 *PointProj) *Point { 109 | p.X.Div(&p1.X, &p1.Z) 110 | p.Y.Div(&p1.Y, &p1.Z) 111 | return p 112 | } 113 | 114 | // FromAffine sets p in projective from p in affine 115 | func (p *PointProj) FromAffine(p1 *Point) *PointProj { 116 | p.X.Set(&p1.X) 117 | p.Y.Set(&p1.Y) 118 | p.Z.SetOne() 119 | return p 120 | } 121 | 122 | // Add adds points in projective coordinates 123 | // cf https://hyperelliptic.org/EFD/g1p/auto-twisted-projective.html 124 | func (p *PointProj) Add(p1, p2 *PointProj) *PointProj { 125 | 126 | var res PointProj 127 | 128 | ecurve := GetEdwardsCurve() 129 | 130 | var A, B, C, D, E, F, G, H, I fr.Element 131 | A.Mul(&p1.Z, &p2.Z) 132 | B.Square(&A) 133 | C.Mul(&p1.X, &p2.X) 134 | D.Mul(&p1.Y, &p2.Y) 135 | E.Mul(&ecurve.D, &C).Mul(&E, &D) 136 | F.Sub(&B, &E) 137 | G.Add(&B, &E) 138 | H.Add(&p1.X, &p1.Y) 139 | I.Add(&p2.X, &p2.Y) 140 | res.X.Mul(&H, &I). 141 | Sub(&res.X, &C). 142 | Sub(&res.X, &D). 143 | Mul(&res.X, &p1.Z). 144 | Mul(&res.X, &F) 145 | H.Mul(&ecurve.A, &C) 146 | res.Y.Sub(&D, &H). 147 | Mul(&res.Y, &p.Z). 148 | Mul(&res.Y, &G) 149 | res.Z.Mul(&F, &G) 150 | 151 | p.Set(&res) 152 | return p 153 | } 154 | 155 | // Double adds points in projective coordinates 156 | // cf https://hyperelliptic.org/EFD/g1p/auto-twisted-projective.html 157 | func (p *PointProj) Double(p1 *PointProj) *PointProj { 158 | 159 | var res PointProj 160 | 161 | ecurve := GetEdwardsCurve() 162 | 163 | var B, C, D, E, F, H, J, tmp fr.Element 164 | 165 | B.Add(&p1.X, &p1.Y).Square(&B) 166 | C.Square(&p1.X) 167 | D.Square(&p1.Y) 168 | E.Mul(&ecurve.A, &C) 169 | F.Add(&E, &D) 170 | H.Square(&p1.Z) 171 | tmp.Double(&H) 172 | J.Sub(&F, &tmp) 173 | res.X.Sub(&B, &C). 174 | Sub(&res.X, &D). 175 | Mul(&res.X, &J) 176 | res.Y.Sub(&E, &D).Mul(&res.Y, &F) 177 | res.Z.Mul(&F, &J) 178 | 179 | p.Set(&res) 180 | return p 181 | } 182 | 183 | // ScalarMul scalar multiplication of a point 184 | // p1 points on the twisted Edwards curve 185 | // c parameters of the twisted Edwards curve 186 | // scal scalar NOT in Montgomery form 187 | // modifies p 188 | func (p *Point) ScalarMul(p1 *Point, scalar fr.Element) *Point { 189 | 190 | var resProj, p1Proj PointProj 191 | resProj.X.SetZero() 192 | resProj.Y.SetOne() 193 | resProj.Z.SetOne() 194 | 195 | p1Proj.FromAffine(p1) 196 | 197 | const wordSize = bits.UintSize 198 | 199 | for i := 4 - 1; i >= 0; i-- { 200 | for j := 0; j < wordSize; j++ { 201 | resProj.Double(&resProj) 202 | b := (scalar[i] & (uint64(1) << uint64(wordSize-1-j))) >> uint64(wordSize-1-j) 203 | if b == 1 { 204 | resProj.Add(&resProj, &p1Proj) 205 | } 206 | } 207 | } 208 | 209 | p.FromProj(&resProj) 210 | 211 | return p 212 | } 213 | -------------------------------------------------------------------------------- /ecc/bn256/twistededwards/twistededwards.go: -------------------------------------------------------------------------------- 1 | package twistededwards 2 | 3 | import ( 4 | "math/big" 5 | "sync" 6 | 7 | "github.com/consensys/gurvy/bn256/fr" 8 | ) 9 | 10 | // CurveParams curve parameters: ax^2 + y^2 = 1 + d*x^2*y^2 11 | type CurveParams struct { 12 | A, D fr.Element // in Montgomery form 13 | Cofactor fr.Element // not in Montgomery form 14 | Order big.Int 15 | Base Point 16 | } 17 | 18 | var edwards CurveParams 19 | var initOnce sync.Once 20 | 21 | // GetEdwardsCurve returns the twisted Edwards curve on BN256's Fr 22 | func GetEdwardsCurve() CurveParams { 23 | initOnce.Do(initEdBN256) 24 | return edwards 25 | } 26 | 27 | func initEdBN256() { 28 | 29 | edwards.A.SetUint64(168700) 30 | edwards.D.SetUint64(168696) 31 | edwards.Cofactor.SetUint64(8).FromMont() 32 | edwards.Order.SetString("2736030358979909402780800718157159386076813972158567259200215660948447373041", 10) 33 | 34 | edwards.Base.X.SetString("5299619240641551281634865583518297030282874472190772894086521144482721001553") 35 | edwards.Base.Y.SetString("16950150798460657717958625567821834550301663161624707787222815936182638968203") 36 | } 37 | -------------------------------------------------------------------------------- /ecc/bn256/twistededwards/twistededwards_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 ConsenSys 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package twistededwards 18 | 19 | import ( 20 | "testing" 21 | 22 | "github.com/consensys/gurvy/bn256/fr" 23 | ) 24 | 25 | func TestAdd(t *testing.T) { 26 | 27 | var p1, p2 Point 28 | 29 | p1.X.SetString("8728367628344135467582547753719073727968275979035063555332785894244029982715") 30 | p1.Y.SetString("8834462946188529904793384347374734779374831553974460136522409595751449858199") 31 | 32 | p2.X.SetString("9560056125663567360314373555170485462871740364163814576088225107862234393497") 33 | p2.Y.SetString("13024071698463677601393829581435828705327146000694268918451707151508990195684") 34 | 35 | var expectedX, expectedY fr.Element 36 | 37 | expectedX.SetString("15602730788680306249246507407102613100672389871136626657306339018592280799798") 38 | expectedY.SetString("9214827499166027327226786359816287546740571844393227610238633031200971415079") 39 | 40 | p1.Add(&p1, &p2) 41 | 42 | if !p1.X.Equal(&expectedX) { 43 | t.Fatal("wrong x coordinate") 44 | } 45 | if !p1.Y.Equal(&expectedY) { 46 | t.Fatal("wrong y coordinate") 47 | } 48 | 49 | } 50 | 51 | func TestAddProj(t *testing.T) { 52 | 53 | var p1, p2 Point 54 | var p1proj, p2proj PointProj 55 | 56 | p1.X.SetString("8728367628344135467582547753719073727968275979035063555332785894244029982715") 57 | p1.Y.SetString("8834462946188529904793384347374734779374831553974460136522409595751449858199") 58 | 59 | p2.X.SetString("9560056125663567360314373555170485462871740364163814576088225107862234393497") 60 | p2.Y.SetString("13024071698463677601393829581435828705327146000694268918451707151508990195684") 61 | 62 | p1proj.FromAffine(&p1) 63 | p2proj.FromAffine(&p2) 64 | 65 | var expectedX, expectedY fr.Element 66 | 67 | expectedX.SetString("15602730788680306249246507407102613100672389871136626657306339018592280799798") 68 | expectedY.SetString("9214827499166027327226786359816287546740571844393227610238633031200971415079") 69 | 70 | p1proj.Add(&p1proj, &p2proj) 71 | p1.FromProj(&p1proj) 72 | 73 | if !p1.X.Equal(&expectedX) { 74 | t.Fatal("wrong x coordinate") 75 | } 76 | if !p1.Y.Equal(&expectedY) { 77 | t.Fatal("wrong y coordinate") 78 | } 79 | 80 | } 81 | 82 | func TestDouble(t *testing.T) { 83 | 84 | var p Point 85 | 86 | p.X.SetString("8728367628344135467582547753719073727968275979035063555332785894244029982715") 87 | p.Y.SetString("8834462946188529904793384347374734779374831553974460136522409595751449858199") 88 | 89 | p.Double(&p) 90 | 91 | var expectedX, expectedY fr.Element 92 | 93 | expectedX.SetString("17048188201798084482613703497237052386773720266456818725024051932759787099830") 94 | expectedY.SetString("15722506141850766164380928609287974914029282300941585435780118880890915697552") 95 | 96 | if !p.X.Equal(&expectedX) { 97 | t.Fatal("wrong x coordinate") 98 | } 99 | if !p.Y.Equal(&expectedY) { 100 | t.Fatal("wrong y coordinate") 101 | } 102 | } 103 | 104 | func TestDoubleProj(t *testing.T) { 105 | 106 | var p Point 107 | var pproj PointProj 108 | 109 | p.X.SetString("8728367628344135467582547753719073727968275979035063555332785894244029982715") 110 | p.Y.SetString("8834462946188529904793384347374734779374831553974460136522409595751449858199") 111 | 112 | pproj.FromAffine(&p).Double(&pproj) 113 | 114 | p.FromProj(&pproj) 115 | 116 | var expectedX, expectedY fr.Element 117 | 118 | expectedX.SetString("17048188201798084482613703497237052386773720266456818725024051932759787099830") 119 | expectedY.SetString("15722506141850766164380928609287974914029282300941585435780118880890915697552") 120 | 121 | if !p.X.Equal(&expectedX) { 122 | t.Fatal("wrong x coordinate") 123 | } 124 | if !p.Y.Equal(&expectedY) { 125 | t.Fatal("wrong y coordinate") 126 | } 127 | } 128 | 129 | func TestScalarMul(t *testing.T) { 130 | 131 | // set curve parameters 132 | ed := GetEdwardsCurve() 133 | 134 | var scalar fr.Element 135 | scalar.SetUint64(23902374).FromMont() 136 | 137 | var p Point 138 | p.ScalarMul(&ed.Base, scalar) 139 | 140 | var expectedX, expectedY fr.Element 141 | 142 | expectedX.SetString("2617519824163134005353570974989848134508856877236793995668417237392062754831") 143 | expectedY.SetString("12956808000482532416873382696451950668786244907047953547021024966691314258300") 144 | 145 | if !expectedX.Equal(&p.X) { 146 | t.Fatal("wrong x coordinate") 147 | } 148 | if !expectedY.Equal(&p.Y) { 149 | t.Fatal("wrong y coordinate") 150 | } 151 | 152 | } 153 | -------------------------------------------------------------------------------- /ecc/bn256Utils/bn256Utils.go: -------------------------------------------------------------------------------- 1 | package bn256Utils 2 | 3 | import ( 4 | "golang.org/x/crypto/bn256" 5 | "math/big" 6 | ) 7 | 8 | func G1ScalarBaseMult(a *big.Int) *bn256.G1 { 9 | return new(bn256.G1).ScalarBaseMult(a) 10 | } 11 | 12 | func G1ScalarMult(a *bn256.G1, b *big.Int) *bn256.G1 { 13 | return new(bn256.G1).ScalarMult(a, b) 14 | } 15 | 16 | func G1Add(a, b *bn256.G1) *bn256.G1 { 17 | return new(bn256.G1).Add(a, b) 18 | } 19 | 20 | func G1Neg(a *bn256.G1) *bn256.G1 { 21 | return new(bn256.G1).Neg(a) 22 | } 23 | 24 | func G2ScalarBaseMult(a *big.Int) *bn256.G2 { 25 | return new(bn256.G2).ScalarBaseMult(a) 26 | } 27 | 28 | func G2ScalarMult(a *bn256.G2, b *big.Int) *bn256.G2 { 29 | return new(bn256.G2).ScalarMult(a, b) 30 | } 31 | 32 | func G2Add(a, b *bn256.G2) *bn256.G2 { 33 | return new(bn256.G2).Add(a, b) 34 | } 35 | 36 | func GTScalarMult(a *bn256.GT, b *big.Int) *bn256.GT { 37 | return new(bn256.GT).ScalarMult(a, b) 38 | } 39 | 40 | func GTAdd(a, b *bn256.GT) *bn256.GT { 41 | return new(bn256.GT).Add(a, b) 42 | } 43 | -------------------------------------------------------------------------------- /ecc/id.go: -------------------------------------------------------------------------------- 1 | package ecc 2 | 3 | // do not modify the order of this enum 4 | const ( 5 | UNKNOWN ID = iota 6 | BLS377 7 | BLS381 8 | BN256 9 | ) 10 | 11 | // ID represent a unique ID for a curve 12 | // (used in serialization checks) 13 | type ID uint16 14 | 15 | func (id ID) String() string { 16 | switch id { 17 | case BLS377: 18 | return "bls377" 19 | case BLS381: 20 | return "bls381" 21 | case BN256: 22 | return "bn256" 23 | default: 24 | panic("unimplemented curve ID") 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ecc/internal/debug/assert_debug.go: -------------------------------------------------------------------------------- 1 | // +build debug 2 | 3 | package debug 4 | 5 | import "fmt" 6 | 7 | func init() { 8 | fmt.Println("WARNING -- DEBUG FLAG IS ON") 9 | } 10 | 11 | // Assert does nothing if debug flag is not provided 12 | // if debug flag is provided, panics if condition is false. 13 | func Assert(condition bool, message ...string) { 14 | if !condition { 15 | if len(message) > 0 { 16 | panic(message[0]) 17 | } else { 18 | panic("assertion failed") 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ecc/internal/debug/assert_release.go: -------------------------------------------------------------------------------- 1 | // +build !debug 2 | 3 | package debug 4 | 5 | // Assert does nothing if debug flag is not provided 6 | // if debug flag is provided, panics if condition is false. 7 | func Assert(condition bool, message ...string) { 8 | } 9 | -------------------------------------------------------------------------------- /ecc/internal/pool/pool.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 ConsenSys 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package pool 18 | 19 | import ( 20 | "runtime" 21 | "sync" 22 | ) 23 | 24 | // Push schedules a function to be executed. 25 | // if it's high priority and the job queue is full, executes synchronously the call 26 | func Push(fn func(), highPriority bool) { 27 | getPool().push(fn, highPriority) 28 | } 29 | 30 | // Execute process in parallel the work function and wait for result 31 | func Execute(iStart, iEnd int, work func(int, int), highPriority bool) { 32 | <-ExecuteAsync(iStart, iEnd, work, highPriority) 33 | } 34 | 35 | // ExecuteAsync process in parallel the work function and return a channel that notifies caller when 36 | // work is done 37 | func ExecuteAsync(iStart, iEnd int, work func(int, int), highPriority bool) chan bool { 38 | pool := getPool() 39 | 40 | interval := iEnd / runtime.NumCPU() 41 | if interval >= iEnd { 42 | interval = iEnd - 1 43 | } 44 | if interval < 1 { 45 | interval = 1 46 | } 47 | var wg sync.WaitGroup 48 | start := 0 49 | for start = iStart; start < iEnd; start += interval { 50 | wg.Add(1) 51 | _start := start 52 | _end := start + interval 53 | if _end > iEnd { 54 | _end = iEnd 55 | } 56 | pool.push(func() { 57 | work(_start, _end) 58 | wg.Done() 59 | }, highPriority) 60 | } 61 | chDone := make(chan bool, 1) 62 | go func() { 63 | wg.Wait() 64 | chDone <- true 65 | }() 66 | return chDone 67 | } 68 | 69 | var initOnce sync.Once 70 | var globalPool *pool 71 | 72 | type pool struct { 73 | chLow, chHigh chan func() 74 | chJob chan struct{} 75 | } 76 | 77 | func worker(pool *pool) { 78 | for range pool.chJob { 79 | select { 80 | // if we have a high priority job, execute it. 81 | case job := <-pool.chHigh: 82 | job() 83 | default: 84 | // else, dequeue low priority task 85 | job := <-pool.chLow 86 | job() 87 | } 88 | 89 | } 90 | } 91 | 92 | func init() { 93 | _ = getPool() 94 | } 95 | 96 | func getPool() *pool { 97 | initOnce.Do(func() { 98 | nbCpus := runtime.NumCPU() 99 | globalPool = &pool{ 100 | chLow: make(chan func(), nbCpus*10), // TODO nbCpus only? 101 | chHigh: make(chan func(), nbCpus*10), 102 | chJob: make(chan struct{}, 20*(nbCpus)), 103 | } 104 | 105 | for i := 0; i < nbCpus; i++ { 106 | go worker(globalPool) 107 | } 108 | }) 109 | return globalPool 110 | } 111 | 112 | func (pool *pool) push(fn func(), highPriority bool) { 113 | if highPriority { 114 | select { 115 | case pool.chHigh <- fn: 116 | default: 117 | // channel is full, calling go routine is executing the function synchronously instead 118 | // this should be used only in the recursive FFT setting 119 | // because caller is already a worker from this pool 120 | fn() 121 | return 122 | } 123 | } else { 124 | pool.chLow <- fn 125 | } 126 | pool.chJob <- struct{}{} 127 | } 128 | -------------------------------------------------------------------------------- /ecc/internal/tests/donotremove.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherLzp/scrypto/60ae416361d692ba2c7a57b8cccd87b1c30995f8/ecc/internal/tests/donotremove.txt -------------------------------------------------------------------------------- /ecc/p256Utils/p256Utils.go: -------------------------------------------------------------------------------- 1 | package p256Utils 2 | 3 | import ( 4 | "crypto/ecdsa" 5 | "crypto/elliptic" 6 | "crypto/rand" 7 | "encoding/hex" 8 | "errors" 9 | "golang.org/x/crypto/bn256" 10 | "math/big" 11 | "regexp" 12 | ) 13 | 14 | type CurvePoint = ecdsa.PublicKey 15 | 16 | const ( 17 | HEX_PREFIX = "0x" 18 | ) 19 | 20 | var ( 21 | p256 = elliptic.P256() 22 | N = p256.Params().N 23 | two = new(big.Int).SetInt64(2) 24 | ) 25 | 26 | func ScalarBaseMult(a *big.Int) (*CurvePoint) { 27 | x, y := p256.ScalarBaseMult(a.Bytes()) 28 | return &CurvePoint{ 29 | Curve: p256, 30 | X: x, 31 | Y: y, 32 | } 33 | } 34 | 35 | func ScalarMult(a *CurvePoint, b *big.Int) (*CurvePoint) { 36 | x, y := p256.ScalarMult(a.X, a.Y, b.Bytes()) 37 | return &CurvePoint{ 38 | Curve: p256, 39 | X: x, 40 | Y: y, 41 | } 42 | } 43 | 44 | func ScalarAdd(a, b *CurvePoint) (*CurvePoint) { 45 | x, y := p256.Add(a.X, a.Y, b.X, b.Y) 46 | return &CurvePoint{ 47 | Curve: p256, 48 | X: x, 49 | Y: y, 50 | } 51 | } 52 | 53 | func IsOnCurve(a *CurvePoint) bool { 54 | isOnCurve := p256.IsOnCurve(a.X, a.Y) 55 | return isOnCurve 56 | } 57 | 58 | func Marshal(a *CurvePoint) (res []byte) { 59 | res = elliptic.Marshal(p256, a.X, a.Y) 60 | return res 61 | } 62 | 63 | func Unmarshal(aBytes []byte) (point *CurvePoint) { 64 | x, y := elliptic.Unmarshal(p256, aBytes) 65 | point = &CurvePoint{ 66 | Curve: p256, 67 | X: x, 68 | Y: y, 69 | } 70 | return point 71 | } 72 | 73 | func IsEqual(a, b *CurvePoint) (res bool) { 74 | return hex.EncodeToString(Marshal(a)) == hex.EncodeToString(Marshal(b)) 75 | } 76 | 77 | // CheckHex : check whether a string is a hex number with prefix "0x" 78 | func CheckHex(s string, length int) bool { 79 | hexPattern, _ := regexp.Compile("\\b0x[0-9a-fA-F]+\\b") 80 | return hexPattern.MatchString(s) && len(s) == length+2 81 | } 82 | 83 | // convert private key to string 84 | func ConvertSkToStr(privateKey *ecdsa.PrivateKey) string { 85 | return HEX_PREFIX + hex.EncodeToString(privateKey.D.Bytes()) 86 | } 87 | 88 | // convert string to private key 89 | func ConvertSkStrToSk(privateKeyStr string) (sk *ecdsa.PrivateKey, err error) { 90 | if !CheckHex(privateKeyStr, 64) { 91 | return nil, errors.New("private key str length not match") 92 | } 93 | priKeyAsBytes, err := hex.DecodeString(privateKeyStr[2:]) 94 | if err != nil { 95 | return nil, err 96 | } 97 | d := new(big.Int).SetBytes(priKeyAsBytes) 98 | // compute public key 99 | pubKey := ScalarBaseMult(d) 100 | sk = &ecdsa.PrivateKey{ 101 | D: d, 102 | PublicKey: *pubKey, 103 | } 104 | return sk, nil 105 | } 106 | 107 | // convert public key to string 108 | func ConvertPkToStr(publicKey *ecdsa.PublicKey) (pubKeyStr string) { 109 | pubKeyBytes := Marshal(publicKey) 110 | pubKeyStr = hex.EncodeToString(pubKeyBytes) 111 | return HEX_PREFIX + pubKeyStr 112 | } 113 | 114 | // convert public key string to key 115 | func ConvertPkStrToPk(pubKeyStr string) (pubKey *ecdsa.PublicKey, err error) { 116 | if !CheckHex(pubKeyStr, 130) { 117 | return nil, errors.New("public key str not match") 118 | } 119 | pubKeyAsBytes, err := hex.DecodeString(pubKeyStr[2:]) 120 | if err != nil { 121 | return nil, err 122 | } 123 | key := Unmarshal(pubKeyAsBytes) 124 | return key, nil 125 | } 126 | 127 | // map hash value to curve 128 | func HashToCurve(hash []byte) (*big.Int) { 129 | hashInt := new(big.Int).SetBytes(hash) 130 | N := p256.Params().N 131 | return hashInt.Mod(hashInt, N) 132 | } 133 | 134 | func RandomKeyPair() (sk *big.Int, pk *CurvePoint, err error) { 135 | // 生成公私钥 136 | priKey, err := ecdsa.GenerateKey(p256, rand.Reader) 137 | if err != nil { 138 | return nil, nil, err 139 | } 140 | pk = &priKey.PublicKey 141 | sk = priKey.D 142 | return sk, pk, nil 143 | } 144 | 145 | func GenerateKeys() (sk, pk string, err error) { 146 | // 生成公私钥 147 | priKey, err := ecdsa.GenerateKey(p256, rand.Reader) 148 | if err != nil { 149 | return "", "", err 150 | } 151 | pubKey := priKey.PublicKey 152 | sk = ConvertSkToStr(priKey) 153 | pk = ConvertPkToStr(&pubKey) 154 | return sk, pk, nil 155 | } 156 | 157 | func GetBaseGenerator() (base *CurvePoint) { 158 | baseX := p256.Params().Gx 159 | baseY := p256.Params().Gy 160 | base = &CurvePoint{ 161 | Curve: p256, 162 | X: baseX, 163 | Y: baseY, 164 | } 165 | return base 166 | } 167 | 168 | func ComputeH() (h *CurvePoint) { 169 | h = ScalarBaseMult(two) 170 | return h 171 | } 172 | 173 | func ComputeGAndHVec(n int) (gs []*CurvePoint, hs []*CurvePoint) { 174 | h := ComputeH() 175 | for i := 0; i < n; i++ { 176 | index := new(big.Int).SetInt64(int64(i + 2)) 177 | gi := ScalarBaseMult(index) 178 | hi := ScalarMult(h, index) 179 | gs = append(gs, gi) 180 | hs = append(hs, hi) 181 | } 182 | return gs, hs 183 | } 184 | 185 | func ConvertG1ToP256(a *bn256.G1) (point *CurvePoint) { 186 | aInt := new(big.Int).SetBytes(a.Marshal()) 187 | point = ScalarBaseMult(aInt) 188 | return point 189 | } 190 | -------------------------------------------------------------------------------- /ecc/pairingUtil.go: -------------------------------------------------------------------------------- 1 | package ecc 2 | 3 | type PairingUtil struct { 4 | Curve 5 | } 6 | -------------------------------------------------------------------------------- /ecc/utils.go: -------------------------------------------------------------------------------- 1 | package ecc 2 | 3 | import ( 4 | "math/big" 5 | ) 6 | 7 | var ( 8 | zero, one, two, three big.Int 9 | ) 10 | 11 | func init() { 12 | one.SetUint64(1) 13 | two.SetUint64(2) 14 | three.SetUint64(3) 15 | } 16 | 17 | // NafDecomposition gets the naf decomposition of a big number 18 | func NafDecomposition(a *big.Int, result []int8) int { 19 | 20 | length := 0 21 | 22 | // some buffers 23 | var buf, aCopy big.Int 24 | aCopy.Set(a) 25 | 26 | for aCopy.Cmp(&zero) != 0 { 27 | 28 | // if aCopy % 2 == 0 29 | buf.And(&aCopy, &one) 30 | 31 | // aCopy even 32 | if buf.Cmp(&zero) == 0 { 33 | result[length] = 0 34 | } else { // aCopy odd 35 | buf.And(&aCopy, &three) 36 | if buf.Cmp(&three) == 0 { 37 | result[length] = -1 38 | aCopy.Add(&aCopy, &one) 39 | } else { 40 | result[length] = 1 41 | } 42 | } 43 | aCopy.Rsh(&aCopy, 1) 44 | length++ 45 | } 46 | return length 47 | } 48 | -------------------------------------------------------------------------------- /ecc/utils_test.go: -------------------------------------------------------------------------------- 1 | package ecc 2 | 3 | import ( 4 | "math/big" 5 | "testing" 6 | ) 7 | 8 | func TestNafDecomposition(t *testing.T) { 9 | exp := big.NewInt(13) 10 | var result [400]int8 11 | lExp := NafDecomposition(exp, result[:]) 12 | dec := result[:lExp] 13 | 14 | res := [5]int8{1, 0, -1, 0, 1} 15 | for i, v := range dec { 16 | if v != res[i] { 17 | t.Error("Error in NafDecomposition") 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /encryption/ouEnc/ouEnc.go: -------------------------------------------------------------------------------- 1 | package ouEnc 2 | 3 | import ( 4 | "crypto/rand" 5 | "math/big" 6 | ) 7 | 8 | type OUKeyPair struct { 9 | Sk *OUSk `json:"sk"` 10 | Pk *OUPk `json:"pk"` 11 | } 12 | 13 | type OUSk struct { 14 | P, Q *big.Int 15 | } 16 | 17 | type OUPk struct { 18 | N, G *big.Int 19 | } 20 | 21 | var ( 22 | ONE = big.NewInt(1) 23 | ) 24 | 25 | func KeyGen(k int) (keyPair *OUKeyPair, err error) { 26 | p, err := rand.Prime(rand.Reader, k) 27 | q, err := rand.Prime(rand.Reader, k) 28 | if err != nil { 29 | return nil, err 30 | } 31 | pSquare := new(big.Int).Mul(p, p) 32 | n := new(big.Int).Mul(pSquare, q) 33 | var g *big.Int 34 | pSubOne := new(big.Int).Sub(p, ONE) 35 | lowBound := new(big.Int).Div(n, big.NewInt(2)) 36 | for { 37 | g, err = rand.Int(rand.Reader, n) 38 | if err != nil { 39 | return nil, err 40 | } 41 | if g.Cmp(lowBound) < 0 { 42 | continue 43 | } 44 | temp := new(big.Int).Exp(g, pSubOne, pSquare) 45 | if temp.Cmp(ONE) != 0 { 46 | break 47 | } 48 | } 49 | return &OUKeyPair{Sk: &OUSk{p, q}, Pk: &OUPk{n, g}}, nil 50 | } 51 | 52 | func Enc(pk OUPk, m *big.Int) (c *big.Int, err error) { 53 | n, g := new(big.Int).Set(pk.N), new(big.Int).Set(pk.G) 54 | r, err := rand.Int(rand.Reader, n) 55 | if err != nil { 56 | return nil, err 57 | } 58 | nMulR := r.Mul(n, r) 59 | c = new(big.Int).Exp(g, m.Add(m, nMulR), n) 60 | return c, nil 61 | } 62 | 63 | func Dec(sk OUSk, pk OUPk, c *big.Int) (m *big.Int, err error) { 64 | p := new(big.Int).Set(sk.P) 65 | g := new(big.Int).Set(pk.G) 66 | pSubOne, pSquare := new(big.Int), new(big.Int) 67 | pSubOne.Sub(p, new(big.Int).SetInt64(1)) 68 | pSquare.Mul(p, p) 69 | one := new(big.Int).SetInt64(1) 70 | a := new(big.Int).Exp(c, pSubOne, pSquare) 71 | a = new(big.Int).Sub(a, one) 72 | a = new(big.Int).Div(a, p) 73 | a = new(big.Int).Mod(a, p) 74 | b := new(big.Int).Exp(g, pSubOne, pSquare) 75 | b = new(big.Int).Sub(b, one) 76 | b = new(big.Int).Div(b, p) 77 | b = new(big.Int).Mod(b, p) 78 | bPrime := new(big.Int).ModInverse(b, p) 79 | m = new(big.Int).Mul(a, bPrime) 80 | m = new(big.Int).Mod(m, p) 81 | return m, nil 82 | } 83 | 84 | func TryOnce() { 85 | keyPair, err := KeyGen(256) 86 | if err != nil { 87 | panic(err) 88 | } 89 | //keyPair := OUKeyPair{Sk: &OUSk{P: new(big.Int).SetInt64(3), Q: new(big.Int).SetInt64(5)}, Pk: &OUPk{N: new(big.Int).SetInt64(45), G: new(big.Int).SetInt64(22), H: new(big.Int).SetInt64(37)}} 90 | c1, err := Enc(*keyPair.Pk, big.NewInt(100)) 91 | c2, err := Enc(*keyPair.Pk, big.NewInt(200)) 92 | if err != nil { 93 | panic(err) 94 | } 95 | c1c2 := new(big.Int).Mul(c1, c2) 96 | m, err := Dec(*keyPair.Sk, *keyPair.Pk, c1c2) 97 | if err != nil { 98 | panic(err) 99 | } 100 | println("plain text:", m.String()) 101 | } 102 | -------------------------------------------------------------------------------- /encryption/recrypt/README.md: -------------------------------------------------------------------------------- 1 | # Introduction and Theory 2 | 3 | ![1](assets/1.png) 4 | 5 | ## Prerequisites 6 | 7 | ![2](assets/2.png) 8 | 9 | ## Encrypt 10 | 11 | ![3](assets/3.png) 12 | 13 | ## ReKeyGen 14 | 15 | ![4](assets/4.png) 16 | 17 | ## ReEncryption 18 | 19 | ![5](assets/5.png) 20 | 21 | ## ReCreateKey 22 | 23 | ![6](assets/6.png) 24 | 25 | ## Decrypt 26 | 27 | ![7](assets/7.png) 28 | 29 | # References 30 | 31 | NUNEZ D. UMBRAL: A THRESHOLD PROXY RE-ENCRYPTION SCHEME[J]. -------------------------------------------------------------------------------- /encryption/recrypt/assets/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherLzp/scrypto/60ae416361d692ba2c7a57b8cccd87b1c30995f8/encryption/recrypt/assets/1.png -------------------------------------------------------------------------------- /encryption/recrypt/assets/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherLzp/scrypto/60ae416361d692ba2c7a57b8cccd87b1c30995f8/encryption/recrypt/assets/2.png -------------------------------------------------------------------------------- /encryption/recrypt/assets/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherLzp/scrypto/60ae416361d692ba2c7a57b8cccd87b1c30995f8/encryption/recrypt/assets/3.png -------------------------------------------------------------------------------- /encryption/recrypt/assets/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherLzp/scrypto/60ae416361d692ba2c7a57b8cccd87b1c30995f8/encryption/recrypt/assets/4.png -------------------------------------------------------------------------------- /encryption/recrypt/assets/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherLzp/scrypto/60ae416361d692ba2c7a57b8cccd87b1c30995f8/encryption/recrypt/assets/5.png -------------------------------------------------------------------------------- /encryption/recrypt/assets/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherLzp/scrypto/60ae416361d692ba2c7a57b8cccd87b1c30995f8/encryption/recrypt/assets/6.png -------------------------------------------------------------------------------- /encryption/recrypt/assets/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherLzp/scrypto/60ae416361d692ba2c7a57b8cccd87b1c30995f8/encryption/recrypt/assets/7.png -------------------------------------------------------------------------------- /encryption/recrypt/umbral.go: -------------------------------------------------------------------------------- 1 | package recrypt 2 | 3 | import ( 4 | "bytes" 5 | "crypto/ecdsa" 6 | "crypto/elliptic" 7 | "encoding/gob" 8 | "encoding/hex" 9 | "fmt" 10 | "math/big" 11 | "scrypto/ecc/p256Utils" 12 | "scrypto/encryption/sherAes" 13 | "scrypto/dsa/ecdsa" 14 | sherMath "scrypto/smath" 15 | "scrypto/sutils" 16 | ) 17 | 18 | type CurvePoint = ecdsa.PublicKey 19 | 20 | type Umbral struct { 21 | curve elliptic.Curve 22 | N *big.Int 23 | } 24 | 25 | type Capsule struct { 26 | E *CurvePoint 27 | V *CurvePoint 28 | S *big.Int 29 | } 30 | 31 | func NewRecryptCipher(curve elliptic.Curve) (recryptCipher *Umbral) { 32 | recryptCipher = &Umbral{ 33 | curve: curve, 34 | N: curve.Params().N, 35 | } 36 | return recryptCipher 37 | } 38 | 39 | func (this *Umbral) encryptKeyGen(pubKey *ecdsa.PublicKey) (capsule *Capsule, keyBytes []byte, err error) { 40 | // generate E,V key-pairs 41 | ecdsaSigner := ecdsaUtils.NewECDSA(this.curve) 42 | e, E, err := ecdsaSigner.GenerateKeys() 43 | v, V, err := ecdsaSigner.GenerateKeys() 44 | if err != nil { 45 | return nil, nil, err 46 | } 47 | // get H2(E || V) 48 | EV := sutils.ContactBytes(p256Utils.Marshal(E), p256Utils.Marshal(V)) 49 | h := p256Utils.HashToCurve(EV) 50 | if err != nil { 51 | return nil, nil, err 52 | } 53 | // get s = v + e * H2(E || V) 54 | s := sherMath.Add(v.D, sherMath.Mul(e.D, h, this.N), this.N) 55 | // get (pk_A)^{e+v} 56 | point := p256Utils.ScalarMult(pubKey, sherMath.Add(e.D, v.D, this.N)) 57 | // generate aes key 58 | keyBytes, err = sutils.GetSha3HashBytes(p256Utils.Marshal(point)) 59 | if err != nil { 60 | return nil, nil, err 61 | } 62 | capsule = &Capsule{ 63 | E: E, 64 | V: V, 65 | S: s, 66 | } 67 | return capsule, keyBytes, nil 68 | } 69 | 70 | // Recreate aes key 71 | func (this *Umbral) RecreateAESKeyByMyPriKey(capsule *Capsule, aPriKey *ecdsa.PrivateKey) (keyBytes []byte, err error) { 72 | point := p256Utils.ScalarAdd(capsule.E, capsule.V) 73 | point = p256Utils.ScalarMult(point, aPriKey.D) 74 | // generate aes key 75 | keyBytes, err = sutils.GetSha3HashBytes(p256Utils.Marshal(point)) 76 | if err != nil { 77 | return nil, err 78 | } 79 | return keyBytes, nil 80 | } 81 | 82 | func (this *Umbral) RecreateAESKeyByMyPriKeyStr(capsule *Capsule, aPriKeyStr string) (keyBytes []byte, err error) { 83 | aPriKey, err := p256Utils.ConvertSkStrToSk(aPriKeyStr) 84 | if err != nil { 85 | return nil, err 86 | } 87 | return this.RecreateAESKeyByMyPriKey(capsule, aPriKey) 88 | } 89 | 90 | func (this *Umbral) EncryptMessageByAESKey(message []byte, keyBytes []byte, pubKey *ecdsa.PublicKey) (cipherText []byte, err error) { 91 | // use aes gcm algorithm to encrypt 92 | // mark keyBytes[:12] as nonce 93 | pubKeyBytes := p256Utils.Marshal(pubKey) 94 | aesGCMCipher := sherAes.NewDefaultAesGCM() 95 | cipherText, err = aesGCMCipher.Encrypt(message, keyBytes, pubKeyBytes, nil) 96 | if err != nil { 97 | return nil, err 98 | } 99 | return cipherText, nil 100 | } 101 | 102 | // Encrypt the message 103 | // AES GCM + Proxy Re-Encryption 104 | func (this *Umbral) Encrypt(message []byte, pubKey *ecdsa.PublicKey) (cipherText []byte, capsule *Capsule, err error) { 105 | capsule, keyBytes, err := this.encryptKeyGen(pubKey) 106 | if err != nil { 107 | return nil, nil, err 108 | } 109 | fmt.Println("Origin key:", hex.EncodeToString(keyBytes)) 110 | // use aes gcm algorithm to encrypt 111 | // mark keyBytes[:12] as nonce 112 | aesGCMCipher := sherAes.NewDefaultAesGCM() 113 | cipherText, err = aesGCMCipher.Encrypt(message, keyBytes, keyBytes, nil) 114 | if err != nil { 115 | return nil, nil, err 116 | } 117 | return cipherText, capsule, nil 118 | } 119 | 120 | func (this *Umbral) EncryptByStr(message, pubKeyStr string) (cipherText []byte, capsule *Capsule, err error) { 121 | key, err := p256Utils.ConvertPkStrToPk(pubKeyStr) 122 | if err != nil { 123 | return nil, nil, err 124 | } 125 | return this.Encrypt([]byte(message), key) 126 | } 127 | 128 | // generate re-encryption key and sends it to Server 129 | // rk = sk_A * d^{-1} 130 | func (this *Umbral) ReKeyGen(aPriKey *ecdsa.PrivateKey, bPubKey *ecdsa.PublicKey) (rk *big.Int, pubX *ecdsa.PublicKey, err error) { 131 | // generate x,X key-pair 132 | p256 := elliptic.P256() 133 | ecdsaSigner := ecdsaUtils.NewECDSA(p256) 134 | priX, pubX, err := ecdsaSigner.GenerateKeys() 135 | if err != nil { 136 | return nil, nil, err 137 | } 138 | // get d = H3(X_A || pk_B || pk_B^{x_A}) 139 | Bx := p256Utils.ScalarMult(bPubKey, priX.D) 140 | dPre := sutils.ContactBytes(p256Utils.Marshal(pubX), p256Utils.Marshal(bPubKey), p256Utils.Marshal(Bx)) 141 | d := p256Utils.HashToCurve(dPre) 142 | // rk = sk_A * d^{-1} 143 | rk = sherMath.Mul(aPriKey.D, sherMath.ModInverse(d, this.N), this.N) 144 | return rk, pubX, nil 145 | } 146 | 147 | func (this *Umbral) ReKeyGenByStr(aPriKeyStr, bPubKeyStr string) (rk *big.Int, pubX *ecdsa.PublicKey, err error) { 148 | aPriKey, err := p256Utils.ConvertSkStrToSk(aPriKeyStr) 149 | if err != nil { 150 | return nil, nil, err 151 | } 152 | bPubKey, err := p256Utils.ConvertPkStrToPk(bPubKeyStr) 153 | if err != nil { 154 | return nil, nil, err 155 | } 156 | return this.ReKeyGen(aPriKey, bPubKey) 157 | } 158 | 159 | // Server executes Re-Encryption method 160 | func (this *Umbral) ReEncryption(rk *big.Int, capsule *Capsule) (newCapsule *Capsule, err error) { 161 | // check g^s == V * E^{H2(E || V)} 162 | S := p256Utils.ScalarBaseMult(capsule.S) 163 | h2 := p256Utils.HashToCurve( 164 | sutils.ContactBytes( 165 | p256Utils.Marshal(capsule.E), 166 | p256Utils.Marshal(capsule.V))) 167 | Eh2 := p256Utils.ScalarMult(capsule.E, h2) 168 | VEh2 := p256Utils.ScalarAdd(capsule.V, Eh2) 169 | // if check failed return error 170 | if !p256Utils.IsEqual(S, VEh2) { 171 | return nil, fmt.Errorf("%s", "Capsule not match") 172 | } 173 | // E' = E^{rk}, V' = V^{rk} 174 | newCapsule = &Capsule{ 175 | E: p256Utils.ScalarMult(capsule.E, rk), 176 | V: p256Utils.ScalarMult(capsule.V, rk), 177 | S: capsule.S, 178 | } 179 | return newCapsule, nil 180 | } 181 | 182 | func (this *Umbral) decryptKeyGen(bPriKey *ecdsa.PrivateKey, capsule *Capsule, pubX *ecdsa.PublicKey) (keyBytes []byte, err error) { 183 | // S = X_A^{sk_B} 184 | S := p256Utils.ScalarMult(pubX, bPriKey.D) 185 | SBytes := p256Utils.Marshal(S) 186 | pubBBytes := p256Utils.Marshal(&bPriKey.PublicKey) 187 | pubXBytes := p256Utils.Marshal(pubX) 188 | // recreate d = H3(X_A || pk_B || S) 189 | d := p256Utils.HashToCurve(sutils.ContactBytes(pubXBytes, pubBBytes, SBytes)) 190 | point := p256Utils.ScalarMult(p256Utils.ScalarAdd(capsule.E, capsule.V), d) 191 | keyBytes, err = sutils.GetSha3HashBytes(p256Utils.Marshal(point)) 192 | if err != nil { 193 | return nil, err 194 | } 195 | return keyBytes, nil 196 | } 197 | 198 | // Recreate the aes key then decrypt the cipherText 199 | func (this *Umbral) Decrypt(bPriKey *ecdsa.PrivateKey, capsule *Capsule, pubX *ecdsa.PublicKey, cipherText []byte) (plainText []byte, err error) { 200 | keyBytes, err := this.decryptKeyGen(bPriKey, capsule, pubX) 201 | if err != nil { 202 | return nil, err 203 | } 204 | // recreate aes key = G((E' * V')^d) 205 | // use aes gcm to decrypt 206 | // mark keyBytes[:12] as nonce 207 | aesGCMCipher := sherAes.NewDefaultAesGCM() 208 | plainText, err = aesGCMCipher.Decrypt(cipherText, keyBytes, keyBytes, nil) 209 | if err != nil { 210 | return nil, err 211 | } 212 | return plainText, nil 213 | } 214 | 215 | func (this *Umbral) DecryptByStr(bPriKeyStr string, capsule *Capsule, pubXStr string, cipherText []byte) (plainText []byte, err error) { 216 | bPriKey, err := p256Utils.ConvertSkStrToSk(bPriKeyStr) 217 | if err != nil { 218 | return nil, err 219 | } 220 | pubX, err := p256Utils.ConvertPkStrToPk(pubXStr) 221 | if err != nil { 222 | return nil, err 223 | } 224 | return this.Decrypt(bPriKey, capsule, pubX, cipherText) 225 | } 226 | 227 | // Decrypt by my own private key 228 | func (this *Umbral) DecryptOnMyPriKey(aPriKey *ecdsa.PrivateKey, capsule *Capsule, cipherText []byte) (plainText []byte, err error) { 229 | keyBytes, err := this.RecreateAESKeyByMyPriKey(capsule, aPriKey) 230 | if err != nil { 231 | return nil, err 232 | } 233 | // use aes gcm algorithm to encrypt 234 | // mark keyBytes[:12] as nonce 235 | aesGCMCipher := sherAes.NewDefaultAesGCM() 236 | plainText, err = aesGCMCipher.Decrypt(cipherText, keyBytes, keyBytes, nil) 237 | return plainText, err 238 | } 239 | 240 | func (this *Umbral) DecryptOnMyOwnStrKey(aPriKeyStr string, capsule *Capsule, cipherText []byte) (plainText []byte, err error) { 241 | aPriKey, err := p256Utils.ConvertSkStrToSk(aPriKeyStr) 242 | if err != nil { 243 | return nil, err 244 | } 245 | return this.DecryptOnMyPriKey(aPriKey, capsule, cipherText) 246 | } 247 | 248 | func (this *Umbral) EncodeCapsule(capsule Capsule) (capsuleAsBytes []byte, err error) { 249 | gob.Register(elliptic.P256()) 250 | buf := new(bytes.Buffer) 251 | enc := gob.NewEncoder(buf) 252 | if err = enc.Encode(capsule); err != nil { 253 | return nil, err 254 | } 255 | return buf.Bytes(), nil 256 | } 257 | 258 | func (this *Umbral) DecodeCapsule(capsuleAsBytes []byte) (capsule Capsule, err error) { 259 | capsule = Capsule{} 260 | gob.Register(this.curve) 261 | dec := gob.NewDecoder(bytes.NewBuffer(capsuleAsBytes)) 262 | if err = dec.Decode(&capsule); err != nil { 263 | return capsule, err 264 | } 265 | return capsule, nil 266 | } 267 | 268 | func TryOnce() { 269 | fmt.Println("-----------Umbral Recrypt start-------------") 270 | p256 := elliptic.P256() 271 | recryptCipher := NewRecryptCipher(p256) 272 | ecdsaSigner := ecdsaUtils.NewECDSA(p256) 273 | // Alice Generate Alice key-pair 274 | aPriKey, aPubKey, _ := ecdsaSigner.GenerateKeys() 275 | // Bob Generate Bob key-pair 276 | bPriKey, bPubKey, _ := ecdsaSigner.GenerateKeys() 277 | // plain text 278 | m := []byte("Hello, Proxy Re-Encryption") 279 | fmt.Println("origin message:", string(m)) 280 | // Alice encrypts to get cipherText and capsule 281 | cipherText, capsule, err := recryptCipher.Encrypt(m, aPubKey) 282 | if err != nil { 283 | panic(err) 284 | } 285 | capsuleAsBytes, err := recryptCipher.EncodeCapsule(*capsule) 286 | if err != nil { 287 | panic(err) 288 | } 289 | capsuleTest, err := recryptCipher.DecodeCapsule(capsuleAsBytes) 290 | if err != nil { 291 | panic(err) 292 | } 293 | fmt.Println("capsule before encode:", capsule) 294 | fmt.Println("capsule after decode:", capsuleTest) 295 | fmt.Println("ciphereText:", hex.EncodeToString(cipherText)) 296 | // Test recreate aes key 297 | keyBytes, err := recryptCipher.RecreateAESKeyByMyPriKey(capsule, aPriKey) 298 | if err != nil { 299 | panic(err) 300 | } 301 | fmt.Println("recreate key:", hex.EncodeToString(keyBytes)) 302 | // Alice generates re-encryption key 303 | rk, pubX, err := recryptCipher.ReKeyGen(aPriKey, bPubKey) 304 | if err != nil { 305 | panic(err) 306 | } 307 | fmt.Println("rk:", rk) 308 | // Server executes re-encrypt 309 | newCapsule, err := recryptCipher.ReEncryption(rk, capsule) 310 | if err != nil { 311 | panic(err) 312 | } 313 | // Bob decrypts the cipherText 314 | plainText, err := recryptCipher.Decrypt(bPriKey, newCapsule, pubX, cipherText) 315 | if err != nil { 316 | panic(err) 317 | } 318 | 319 | plainTextByMyPri, err := recryptCipher.DecryptOnMyPriKey(aPriKey, capsule, cipherText) 320 | if err != nil { 321 | panic(err) 322 | } 323 | fmt.Println("PlainText by my own private key:", string(plainTextByMyPri)) 324 | // get plainText 325 | fmt.Println("plainText:", string(plainText)) 326 | fmt.Println("-----------Umbral Recrypt end-------------") 327 | } 328 | -------------------------------------------------------------------------------- /encryption/recrypt/umbral_test.go: -------------------------------------------------------------------------------- 1 | package recrypt 2 | 3 | import ( 4 | "crypto/elliptic" 5 | "encoding/hex" 6 | "fmt" 7 | "scrypto/dsa/ecdsa" 8 | "testing" 9 | ) 10 | 11 | func TestUmbral_Encrypt(t *testing.T) { 12 | p256 := elliptic.P256() 13 | recryptCipher := NewRecryptCipher(p256) 14 | ecdsaSigner := ecdsaUtils.NewECDSA(p256) 15 | // Alice Generate Alice key-pair 16 | _, aPubKey, _ := ecdsaSigner.GenerateKeys() 17 | // Bob Generate Bob key-pair 18 | //_, bPubKey, _ := ecdsaSigner.GenerateKeys() 19 | // plain text 20 | m := []byte("Hello, Proxy Re-Encryption") 21 | fmt.Println("origin message:", string(m)) 22 | // Alice encrypts to get cipherText and capsule 23 | cipherText, capsule, err := recryptCipher.Encrypt(m, aPubKey) 24 | if err != nil { 25 | panic(err) 26 | } 27 | capsuleAsBytes, err := recryptCipher.EncodeCapsule(*capsule) 28 | if err != nil { 29 | panic(err) 30 | } 31 | capsuleTest, err := recryptCipher.DecodeCapsule(capsuleAsBytes) 32 | if err != nil { 33 | panic(err) 34 | } 35 | fmt.Println("capsule before encode:", capsule) 36 | fmt.Println("capsule after decode:", capsuleTest) 37 | fmt.Println("ciphereText:", hex.EncodeToString(cipherText)) 38 | } 39 | 40 | func TestUmbral_ReKeyGen(t *testing.T) { 41 | p256 := elliptic.P256() 42 | recryptCipher := NewRecryptCipher(p256) 43 | ecdsaSigner := ecdsaUtils.NewECDSA(p256) 44 | // Alice Generate Alice key-pair 45 | aPriKey, aPubKey, _ := ecdsaSigner.GenerateKeys() 46 | // Bob Generate Bob key-pair 47 | _, bPubKey, _ := ecdsaSigner.GenerateKeys() 48 | // plain text 49 | m := []byte("Hello, Proxy Re-Encryption") 50 | fmt.Println("origin message:", string(m)) 51 | // Alice encrypts to get cipherText and capsule 52 | cipherText, capsule, err := recryptCipher.Encrypt(m, aPubKey) 53 | if err != nil { 54 | panic(err) 55 | } 56 | capsuleAsBytes, err := recryptCipher.EncodeCapsule(*capsule) 57 | if err != nil { 58 | panic(err) 59 | } 60 | capsuleTest, err := recryptCipher.DecodeCapsule(capsuleAsBytes) 61 | if err != nil { 62 | panic(err) 63 | } 64 | fmt.Println("capsule before encode:", capsule) 65 | fmt.Println("capsule after decode:", capsuleTest) 66 | fmt.Println("ciphereText:", hex.EncodeToString(cipherText)) 67 | // Test recreate aes key 68 | keyBytes, err := recryptCipher.RecreateAESKeyByMyPriKey(capsule, aPriKey) 69 | if err != nil { 70 | panic(err) 71 | } 72 | fmt.Println("recreate key:", hex.EncodeToString(keyBytes)) 73 | // Alice generates re-encryption key 74 | rk, _, err := recryptCipher.ReKeyGen(aPriKey, bPubKey) 75 | if err != nil { 76 | panic(err) 77 | } 78 | fmt.Println("rk:", rk) 79 | } 80 | 81 | func TestUmbral_ReEncryption(t *testing.T) { 82 | p256 := elliptic.P256() 83 | recryptCipher := NewRecryptCipher(p256) 84 | ecdsaSigner := ecdsaUtils.NewECDSA(p256) 85 | // Alice Generate Alice key-pair 86 | aPriKey, aPubKey, _ := ecdsaSigner.GenerateKeys() 87 | // Bob Generate Bob key-pair 88 | _, bPubKey, _ := ecdsaSigner.GenerateKeys() 89 | // plain text 90 | m := []byte("Hello, Proxy Re-Encryption") 91 | fmt.Println("origin message:", string(m)) 92 | // Alice encrypts to get cipherText and capsule 93 | cipherText, capsule, err := recryptCipher.Encrypt(m, aPubKey) 94 | if err != nil { 95 | panic(err) 96 | } 97 | capsuleAsBytes, err := recryptCipher.EncodeCapsule(*capsule) 98 | if err != nil { 99 | panic(err) 100 | } 101 | capsuleTest, err := recryptCipher.DecodeCapsule(capsuleAsBytes) 102 | if err != nil { 103 | panic(err) 104 | } 105 | fmt.Println("capsule before encode:", capsule) 106 | fmt.Println("capsule after decode:", capsuleTest) 107 | fmt.Println("ciphereText:", hex.EncodeToString(cipherText)) 108 | // Test recreate aes key 109 | keyBytes, err := recryptCipher.RecreateAESKeyByMyPriKey(capsule, aPriKey) 110 | if err != nil { 111 | panic(err) 112 | } 113 | fmt.Println("recreate key:", hex.EncodeToString(keyBytes)) 114 | // Alice generates re-encryption key 115 | rk, _, err := recryptCipher.ReKeyGen(aPriKey, bPubKey) 116 | if err != nil { 117 | panic(err) 118 | } 119 | fmt.Println("rk:", rk) 120 | // Server executes re-encrypt 121 | newCapsule, err := recryptCipher.ReEncryption(rk, capsule) 122 | if err != nil { 123 | panic(err) 124 | } 125 | capsuleBytes, err := recryptCipher.EncodeCapsule(*newCapsule) 126 | if err != nil { 127 | panic(err) 128 | } 129 | fmt.Println("newCapsule:", capsuleBytes) 130 | } 131 | 132 | func TestUmbral_Decrypt(t *testing.T) { 133 | p256 := elliptic.P256() 134 | recryptCipher := NewRecryptCipher(p256) 135 | ecdsaSigner := ecdsaUtils.NewECDSA(p256) 136 | // Alice Generate Alice key-pair 137 | aPriKey, aPubKey, _ := ecdsaSigner.GenerateKeys() 138 | // Bob Generate Bob key-pair 139 | bPriKey, bPubKey, _ := ecdsaSigner.GenerateKeys() 140 | // plain text 141 | m := []byte("Hello, Proxy Re-Encryption") 142 | fmt.Println("origin message:", string(m)) 143 | // Alice encrypts to get cipherText and capsule 144 | cipherText, capsule, err := recryptCipher.Encrypt(m, aPubKey) 145 | if err != nil { 146 | panic(err) 147 | } 148 | capsuleAsBytes, err := recryptCipher.EncodeCapsule(*capsule) 149 | if err != nil { 150 | panic(err) 151 | } 152 | capsuleTest, err := recryptCipher.DecodeCapsule(capsuleAsBytes) 153 | if err != nil { 154 | panic(err) 155 | } 156 | fmt.Println("capsule before encode:", capsule) 157 | fmt.Println("capsule after decode:", capsuleTest) 158 | fmt.Println("ciphereText:", hex.EncodeToString(cipherText)) 159 | // Test recreate aes key 160 | keyBytes, err := recryptCipher.RecreateAESKeyByMyPriKey(capsule, aPriKey) 161 | if err != nil { 162 | panic(err) 163 | } 164 | fmt.Println("recreate key:", hex.EncodeToString(keyBytes)) 165 | // Alice generates re-encryption key 166 | rk, pubX, err := recryptCipher.ReKeyGen(aPriKey, bPubKey) 167 | if err != nil { 168 | panic(err) 169 | } 170 | fmt.Println("rk:", rk) 171 | // Server executes re-encrypt 172 | newCapsule, err := recryptCipher.ReEncryption(rk, capsule) 173 | if err != nil { 174 | panic(err) 175 | } 176 | // Bob decrypts the cipherText 177 | plainText, err := recryptCipher.Decrypt(bPriKey, newCapsule, pubX, cipherText) 178 | if err != nil { 179 | panic(err) 180 | } 181 | // get plainText 182 | fmt.Println("plainText:", string(plainText)) 183 | } 184 | -------------------------------------------------------------------------------- /encryption/sherAes/README.md: -------------------------------------------------------------------------------- 1 | # AES GCM 2 | 3 | ![aes_gcm](assets/aes_gcm.png) 4 | 5 | # References 6 | 7 | https://tools.ietf.org/html/rfc5288 -------------------------------------------------------------------------------- /encryption/sherAes/aesGCM.go: -------------------------------------------------------------------------------- 1 | package sherAes 2 | 3 | import ( 4 | "crypto/aes" 5 | "crypto/cipher" 6 | "encoding/hex" 7 | "errors" 8 | "fmt" 9 | ) 10 | 11 | type aesGCM struct { 12 | gcmStandardNonceSize, gcmKeySize int 13 | } 14 | 15 | func NewDefaultAesGCM() (aesGCMCipher *aesGCM) { 16 | aesGCMCipher = &aesGCM{ 17 | gcmStandardNonceSize: 12, 18 | gcmKeySize: 32, 19 | } 20 | return aesGCMCipher 21 | } 22 | 23 | // encrypt message 24 | // @plainText: message you want to encrypt 25 | // @key: key which is used to encrypt 26 | // @iv: nonce which is used in encryption 27 | // @additionalData: data which is used to mask plainText 28 | func (this *aesGCM) Encrypt(plainText []byte, key []byte, iv []byte, additionalData []byte) (cipherText []byte, err error) { 29 | // key size should larger than 32 bytes 30 | if len(key) < this.gcmKeySize { 31 | return nil, errors.New("key size not match: key should larger than 32 bytes") 32 | } 33 | // iv size should larger than 12 bytes 34 | if len(iv) < this.gcmStandardNonceSize { 35 | return nil, errors.New("iv size not match: iv should larger than 12 bytes") 36 | } 37 | // create block cipher 38 | block, err := aes.NewCipher(key[:32]) 39 | if err != nil { 40 | return nil, err 41 | } 42 | // create gcm cipher 43 | aesGCM, err := cipher.NewGCM(block) 44 | if err != nil { 45 | return nil, err 46 | } 47 | // encrypt plainText 48 | cipherText = aesGCM.Seal(nil, iv[:12], plainText, additionalData) 49 | return cipherText, nil 50 | } 51 | 52 | // decrypt encrypted message 53 | // @cipherText: message you want to decrypt 54 | // @key: key which is used to encrypt 55 | // @iv: nonce which is used in encryption 56 | // @additionalData: data which was used to mask plainText 57 | func (this *aesGCM) Decrypt(cipherText []byte, key []byte, iv []byte, additionalData []byte) (plainText []byte, err error) { 58 | // key size should larger than 32 bytes 59 | if len(key) < this.gcmKeySize { 60 | return nil, errors.New("key size not match: key should larger than 32 bytes") 61 | } 62 | // iv size should larger than 12 bytes 63 | if len(iv) < this.gcmStandardNonceSize { 64 | return nil, errors.New("iv size not match: iv should larger than 12 bytes") 65 | } 66 | // create block cipher 67 | block, err := aes.NewCipher(key[:32]) 68 | if err != nil { 69 | return nil, err 70 | } 71 | // create gcm cipher 72 | aesGCM, err := cipher.NewGCM(block) 73 | if err != nil { 74 | return nil, err 75 | } 76 | // decrypt the cipherText 77 | plainText, err = aesGCM.Open(nil, iv[:12], cipherText, additionalData) 78 | if err != nil { 79 | return nil, err 80 | } 81 | return plainText, nil 82 | } 83 | 84 | func TryOnce() { 85 | fmt.Println("-----------AES GCM start-------------") 86 | // create aes gcm cipher 87 | aesGCMCipher := NewDefaultAesGCM() 88 | // message you want to encrypt 89 | plainText := []byte("Hello World") 90 | fmt.Println("PlainText:", string(plainText)) 91 | fmt.Println("plaintext length:", len(plainText)) 92 | // key size should larger than 32 bytes 93 | key := []byte("key:12345678912345678912345678912345789") 94 | // nonce 95 | iv := []byte("iv:123456789123") 96 | cipherText, err := aesGCMCipher.Encrypt(plainText, key, iv, nil) 97 | if err != nil { 98 | panic(err) 99 | } 100 | fmt.Println("CipherText:", hex.EncodeToString(cipherText)) 101 | fmt.Println("cipherText length:", len(cipherText)) 102 | decryptText, err := aesGCMCipher.Decrypt(cipherText, key, iv, nil) 103 | if err != nil { 104 | panic(err) 105 | } 106 | fmt.Println("Text after decryption:", string(decryptText)) 107 | fmt.Println("Text after decryption length:", len(string(decryptText))) 108 | fmt.Println("-----------AES GCM end-------------") 109 | } 110 | -------------------------------------------------------------------------------- /encryption/sherAes/aesGCM_test.go: -------------------------------------------------------------------------------- 1 | package sherAes 2 | 3 | import ( 4 | "encoding/hex" 5 | "fmt" 6 | "testing" 7 | ) 8 | 9 | // test aesGCM encrypt 10 | func TestAesGCM_Encrypt(t *testing.T) { 11 | aesGCMCipher := NewDefaultAesGCM() 12 | // message you want to encrypt 13 | plainText := []byte("Hello World!") 14 | // key size should larger than 32 bytes 15 | key := []byte("key:12345678912345678912345678912345789") 16 | // nonce 17 | iv := []byte("iv:123456789123") 18 | // mask data 19 | additionalData := []byte("additionalData:test") 20 | cipherText, err := aesGCMCipher.Encrypt(plainText, key, iv, additionalData) 21 | if err != nil { 22 | fmt.Println("Encrypt error:", err) 23 | } 24 | fmt.Println("Encrypted text:", hex.EncodeToString(cipherText)) 25 | } 26 | 27 | // test aesGCM decrypt 28 | func TestAesGCM_Decrypt(t *testing.T) { 29 | aesGCMCipher := NewDefaultAesGCM() 30 | cipherText, _ := hex.DecodeString("e50d7983b9cd370d81acdda56f5f6e15765ca3a537071eb18eedc27e") 31 | // key size should larger than 32 bytes 32 | key := []byte("key:12345678912345678912345678912345789") 33 | // nonce 34 | iv := []byte("iv:123456789123") 35 | // mask data 36 | additionalData := []byte("additionalData:test") 37 | plainText, err := aesGCMCipher.Decrypt(cipherText, key, iv, additionalData) 38 | if err != nil { 39 | fmt.Println("Encrypt error:", err) 40 | } 41 | fmt.Println("Plain text:", string(plainText)) 42 | } 43 | -------------------------------------------------------------------------------- /encryption/sherAes/assets/aes_gcm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherLzp/scrypto/60ae416361d692ba2c7a57b8cccd87b1c30995f8/encryption/sherAes/assets/aes_gcm.png -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module scrypto 2 | 3 | go 1.15 4 | 5 | require ( 6 | golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9 7 | github.com/consensys/gurvy v0.1.2-0.20200512111154-1662e289e29b 8 | ) 9 | 10 | require github.com/ethereum/go-ethereum v1.9.14 11 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "scrypto/encryption/ouEnc" 4 | 5 | func main() { 6 | //sherAes.TryOnce() 7 | //sigmaProtocol.TryOnce() 8 | //algebraicMAC.TryOnce() 9 | //recrypt.TryOnce() 10 | //ringers17.TryOnce() 11 | //credentials.TryOnce() 12 | ouEnc.TryOnce() 13 | } 14 | -------------------------------------------------------------------------------- /proof/credentials/README.md: -------------------------------------------------------------------------------- 1 | # Credential Scheme 2 | 3 | $Issue$: 4 | 5 | Common inofrmation between User and Issuer: 6 | 7 | Attributes:$k_1,...,k_n$,issuer's public key:$\sigma = (p,e,Q,A,A_0,...,A_n,Z)$ 8 | 9 | Issuer: 10 | 11 | public $\bar{S} = \bar{K}^a,\bar{S_0} = \bar{K}^{a_0}$ where $\bar{K} \in_R G_1$ 12 | 13 | User: 14 | $$ 15 | choose \ \alpha,\kappa' \in_R \mathbb{Z}_p^* \\set \ S = \bar{S}^{\alpha},S_0 = \bar{S_0}^{\alpha} \\PK\{(\kappa',k_0): R=S^{\kappa'} S_0^{k_0} \} \\sends \ S,S_0,R=S^{\kappa'} S_0^{k_0} \text{ to issuer} 16 | $$ 17 | Issuer: 18 | $$ 19 | set \ K = S^{1/a} \\verify \ S \neq \bar{S},K = S_0^{1/a_0} \\choose \ \kappa'' \in_R \mathbb{Z}_p \\set \ S_i = K^{a_i},\forall i \in[1,n] \\set \ T = (K S^{\kappa''} R \prod_{i=1}^n S_i^{k_i})^z \\sends \ \kappa'',K,S_1,...,S_n,T \text{ to user} 20 | $$ 21 | User: 22 | $$ 23 | set \ \kappa = \kappa' + \kappa'' \\return \ (k_0,...,k_n),(\kappa,K,S,S_0,...,S_n,T) 24 | $$ 25 | $ShowCredential$: 26 | 27 | Common information between User and Verifier: 28 | 29 | Issuer's public key $\sigma = (p,e,Q,A,A_0,...,A_n,Z)$, disclosure set $\mathcal{D}$, undisclosed set $\mathcal{C} = \{1,...,n \} \setminus \mathcal{D}$, disclosed attributes: $(k_i)_{i \in D}$ 30 | 31 | User: 32 | $$ 33 | C = K S^{\kappa} S_0^{k_0} ... S_n^{k_n} \\ 34 | knows \ K,S,S_0,...,S_n,\kappa,(k_i)_{i \in \mathcal{C}},C,T \\ 35 | choose \ \alpha,\beta \in_R \mathbb{Z}_p^* \\ 36 | set \ \bar{K} = K^{\alpha}, \bar{S} = S^{\alpha},\bar{S}_i = S_i^{\alpha} \forall i \in [0,n] \\ 37 | set \ \tilde{C} = C^{\alpha \cdot \beta}, \tilde{T} = T^{\alpha \cdot \beta} \\ 38 | set \ R = \bar{K} \prod_{i \in D} \bar{S_i}^{k_i} \\ 39 | PK\{(\beta,\kappa,k_0,(k_i)_{i \in \mathcal{C}}): \tilde{C} = R^{\beta} \bar{S}^{\kappa \cdot \beta} \bar{S_0}^{k_0 \cdot \beta} \prod_{i \in \mathcal{C}} \bar{S_i}^{k_i \cdot \beta} \} \\ 40 | sends \ \bar{K},\bar{S},(\bar{S_i})_{i=0,...,n},\tilde{C},\tilde{T} \text{ to Verifier} 41 | $$ 42 | $Verify$: 43 | 44 | Verifier: 45 | $$ 46 | Verify \ ZK \ Proof \\choose \ r,r_0,...,r_n \in_R \mathbb{Z}_p^* \\ 47 | verify \ e(\tilde{C},Z) \overset{?}{=} e(\tilde{T},Q) \\ 48 | and \ e(\bar{S}^r \prod_{i=0}^n \bar{S_i}^{r_i},Q) \overset{?}{=} e(\bar{K},A^r \prod_{i=0}^n A_i^{r_i}) 49 | $$ 50 | 51 | 52 | 53 | 54 | 55 | $PK\{(\beta,\kappa,k_0,(k_i)_{i \in \mathcal{C}}): \tilde{C} = R^{\beta} \bar{S}^{\kappa \cdot \beta} \bar{S_0}^{k_0 \cdot \beta} \prod_{i \in \mathcal{C}} \bar{S_i}^{k_i \cdot \beta} \}$: 56 | 57 | 关系等式$R$: 58 | $$ 59 | R = \bar{K} \prod_{i \in \mathcal{D}} \bar{S_i}^{k_i} \\ 60 | \tilde{C} = C^{\alpha \cdot \beta} 61 | $$ 62 | 先验证关系等式是否成立: 63 | $$ 64 | \tilde{C} = (\bar{K} \prod_{i \in \mathcal{D}} \bar{S_i}^{k_i}) ^{\beta} \bar{S}^{\kappa \beta} \bar{S_0}^{k_0 \beta} \prod_{i \in \mathcal{C}} \bar{S_i}^{k_i \beta} \\ 65 | \tilde{C} = (K S^{\kappa} \prod_{i \in [0,n]} S_i^{k_i} )^{\alpha \beta} \\ 66 | \tilde{C} = C^{\alpha \beta} 67 | $$ 68 | 秘密: 69 | 70 | $(\beta,\kappa \beta,(k_i \beta)_{i \in \mathcal{C}})$ 71 | 72 | 已知公共参数: 73 | 74 | $R,\bar{S},(\bar{S_i})_{i \in \mathcal{C}}$ 75 | 76 | Prover: 77 | $$ 78 | r_i,i = [0,len(secretCount)) \in_R \mathbb{Z}_p, i \in \mathcal{C} \\ 79 | t_0 := R^{r_0},t_1 := \bar{S}^{r_1},t_i := \bar{S_i}^{r_i},i=[2,secretCount) \\ 80 | t = \prod_{i = [0,len(secretCount))} t_i \\ 81 | c = H(g \| t \| A \| H(k_i)) \\ 82 | s_0 := r_0 - c \beta\\ 83 | s_1 := r_1 - c \kappa \beta \\ 84 | s_i = r_i - c k_i \beta \\ 85 | $$ 86 | Verifier: 87 | $$ 88 | t = R^{s_0} \cdot \bar{S}^{s_1} \cdot \bar{S_i}^{s_i} \cdot \tilde{C}^{c} \\ 89 | t = R^{s_0} \cdot \bar{S}^{s_1} \cdot \bar{S_i}^{s_i} \cdot (\bar{C}^{\beta})^{c} \\ 90 | t = (R)^{r_0 - c\beta} \cdot \bar{S}^{r_1 - c \kappa \beta} \cdot (\prod_{i \in \mathcal{C}} \bar{S_i}^{r_i - c k_i \beta}) \cdot (R \cdot \bar{S} \cdot \prod_{i \in \mathcal{C}}\bar{S_i}^{k_i})^{c \beta} \\ 91 | t = R^{r_0} \cdot \bar{S}^{r_1} \cdot \prod_{i \in \mathcal{C}}\bar{S_i}^{k_i} \\ 92 | t = \prod_{i = [0,n]} t_i 93 | $$ 94 | 95 | # References 96 | 97 | Ringers S, Verheul E, Hoepman J H. An efficient self-blindable attribute-based credential scheme[C]//International Conference on Financial Cryptography and Data Security. Springer, Cham, 2017: 3-20. -------------------------------------------------------------------------------- /proof/credentials/ringers17.go: -------------------------------------------------------------------------------- 1 | package credentials 2 | 3 | import ( 4 | "crypto/rand" 5 | "errors" 6 | "fmt" 7 | "golang.org/x/crypto/bn256" 8 | "math/big" 9 | "scrypto/ecc/bn256Utils" 10 | "scrypto/proof/sigmaProtocol" 11 | "scrypto/dsa/ringers17" 12 | sherMath "scrypto/smath" 13 | "scrypto/sutils" 14 | ) 15 | 16 | type ringersCredential struct { 17 | P *big.Int 18 | } 19 | 20 | type Credential struct { 21 | Keys []string 22 | Claim map[string]*big.Int 23 | Sigma *ringers17.Sigma 24 | Proof *sigmaProtocol.ProveScheme 25 | IsSelective bool 26 | } 27 | 28 | func (credential *Credential) AddClaimInfo(key string, value *big.Int) { 29 | if credential.Claim != nil { 30 | if _, ok := credential.Claim[key]; ok { // if key already exists 31 | credential.Claim[key] = value 32 | } else { // if key not exists 33 | credential.Claim[key] = value 34 | credential.Keys = append(credential.Keys, key) 35 | } 36 | } 37 | } 38 | 39 | func NewRingersCredential() (credentialScheme *ringersCredential) { 40 | credentialScheme = &ringersCredential{ 41 | P: bn256.Order, 42 | } 43 | return credentialScheme 44 | } 45 | 46 | func (ringers *ringersCredential) ProverKeyGen() (sk *big.Int, pk *bn256.G1, err error) { 47 | sk, pk, err = bn256.RandomG1(rand.Reader) 48 | if err != nil { 49 | return nil, nil, err 50 | } 51 | return sk, pk, nil 52 | } 53 | 54 | // issue credential 55 | func (ringers *ringersCredential) Issue(claim map[string]*big.Int, sk []*big.Int) (credential *Credential, err error) { 56 | ringersSigner := ringers17.NewSigOfRingers() 57 | var keys []string 58 | var ks []*big.Int 59 | for key, attribute := range claim { 60 | keys = append(keys, key) 61 | ks = append(ks, attribute) 62 | } 63 | sigma, err := ringersSigner.Sign(ks, sk) 64 | if err != nil { 65 | return nil, err 66 | } 67 | credential = new(Credential) 68 | credential.Keys = keys 69 | credential.Claim = claim 70 | credential.Sigma = sigma 71 | return credential, nil 72 | } 73 | 74 | // hide attributes 75 | func hideAttributes(claim map[string]*big.Int, C map[string]bool) (hidedPairs map[string]*big.Int, err error) { 76 | hidedPairs = make(map[string]*big.Int) 77 | // find which attribute needs to be hided 78 | for key, attribute := range claim { 79 | if _, ok := C[key]; ok { 80 | // calculate commitment 81 | commitmentBytes, err := sutils.ComputeCommitmentBytes(claim[key]) 82 | if err != nil { 83 | return nil, err 84 | } 85 | ai := new(big.Int).SetBytes(commitmentBytes) 86 | hidedPairs[key] = ai 87 | } else { 88 | hidedPairs[key] = attribute 89 | } 90 | } 91 | return hidedPairs, nil 92 | } 93 | 94 | // 展示凭证,选择性披露 95 | func (ringers *ringersCredential) ShowCredential(credential *Credential, pk *bn256.G1, C map[string]bool) (selectiveCredential *Credential, err error) { 96 | // create a new credential 97 | selectiveCredential = new(Credential) 98 | // get dsa 99 | oldSigma := credential.Sigma 100 | // hide attributes 101 | // subSet is the hided attributes set 102 | hidedPairs, err := hideAttributes(credential.Claim, C) 103 | if err != nil { 104 | return nil, err 105 | } 106 | // re-randomize sigma 107 | ringersSigner := ringers17.NewSigOfRingers() 108 | beta, newSigma, err := ringersSigner.ReRandomizeSignature(oldSigma) 109 | if err != nil { 110 | return nil, err 111 | } 112 | selectiveCredential.Sigma = newSigma 113 | selectiveCredential.Keys = credential.Keys 114 | selectiveCredential.Claim = hidedPairs 115 | // SPK{(\beta,\kappa,(k_i)_{i \in \mathcal{C}}): C = \tilde{C}^{\beta} * \bar{S}^{\kappa} * \bar{S_i}^{k_i} } 116 | // i \in \mathcal{C} 117 | nizk := sigmaProtocol.NewSigmaNIZK(ringers.P) 118 | // secret: \beta, \kappa * \beta , k_i * \beta 119 | // public: C, \bar{S}, \bar{S_i} 120 | // C = \bar{K} * \prod_{i \in \mathcal{C}} \bar{S_i}^{k_i} 121 | R := newSigma.K 122 | //var optionDataPre []byte 123 | for i, key := range credential.Keys { 124 | attr := credential.Claim[key] 125 | if _, ok := C[key]; ok { 126 | ki_beta := sherMath.Mul(attr, beta, nizk.P) 127 | ssi := newSigma.Ss[i] 128 | nizk.AddPair(ki_beta, ssi) 129 | } else { 130 | Si_ki := bn256Utils.G1ScalarMult(newSigma.Ss[i], attr) 131 | R = bn256Utils.G1Add(R, Si_ki) 132 | } 133 | } 134 | nizk.AddPair(beta, R) 135 | kappa_beta := sherMath.Mul(newSigma.Kappa, beta, ringers.P) 136 | nizk.AddPair(kappa_beta, newSigma.S) 137 | // optionData H(k_i) i \in \mathcal{C} 138 | //optionData, err := sutils.GetSha3HashBytes(optionDataPre) 139 | //if err != nil { 140 | // return nil, err 141 | //} 142 | prove, err := nizk.Prove(newSigma.C, pk, nil) 143 | if err != nil { 144 | return nil, err 145 | } 146 | selectiveCredential.Proof = prove 147 | selectiveCredential.IsSelective = true 148 | return selectiveCredential, nil 149 | } 150 | 151 | func (ringers *ringersCredential) Verify(credential *Credential, optionData []byte, pk *ringers17.RingersPK) (res bool, err error) { 152 | var ks []*big.Int 153 | for _, key := range credential.Keys { 154 | if _, ok := credential.Claim[key]; !ok { 155 | return false, errors.New("error with the mapping keys") 156 | } 157 | ks = append(ks, credential.Claim[key]) 158 | } 159 | // verify credential dsa 160 | ringersSigner := ringers17.NewSigOfRingers() 161 | res, err = ringersSigner.Verify(ks, credential.Sigma, pk) 162 | // verify selective credential 163 | if credential.IsSelective && credential.Proof != nil { 164 | // verify zk proof 165 | nizk := sigmaProtocol.NewSigmaNIZK(ringers.P) 166 | zkRes, err := nizk.Verify(credential.Proof, optionData) 167 | if err != nil { 168 | return false, err 169 | } 170 | res = res && zkRes 171 | } 172 | return res, nil 173 | } 174 | 175 | func TryOnce() { 176 | fmt.Println("-----------Anonymous Credential start-------------") 177 | ringersSigner := ringers17.NewSigOfRingers() 178 | sk, pk, err := ringersSigner.KeyGen(2) 179 | if err != nil { 180 | panic(err) 181 | } 182 | claim := make(map[string]*big.Int) 183 | claim["name"] = new(big.Int).SetBytes([]byte("Sher")) 184 | claim["identity number"] = new(big.Int).SetBytes([]byte("330xxxxxxxxx")) 185 | claim["birthday"] = new(big.Int).SetBytes([]byte("1995-05-09")) 186 | credentialScheme := NewRingersCredential() 187 | credential, err := credentialScheme.Issue(claim, sk) 188 | if err != nil { 189 | panic(err) 190 | } 191 | fmt.Println("Credential:", credential) 192 | for k, v := range credential.Claim { 193 | fmt.Printf("Key is: %s, Value is: %s \n", k, v.Bytes()) 194 | } 195 | // verify dsa 196 | var attributes []*big.Int 197 | for _, attribute := range credential.Claim { 198 | attributes = append(attributes, attribute) 199 | } 200 | newCredVerify, err := credentialScheme.Verify(credential, nil, pk) 201 | if err != nil { 202 | panic(err) 203 | } 204 | fmt.Println("Verify origin credential:", newCredVerify) 205 | _, A, _ := credentialScheme.ProverKeyGen() 206 | C := make(map[string]bool) 207 | C["name"] = true 208 | C["birthday"] = true 209 | selectiveCredential, err := credentialScheme.ShowCredential(credential, A, C) 210 | if err != nil { 211 | panic(err) 212 | } 213 | fmt.Println("SelectiveCredential:", selectiveCredential) 214 | for k, v := range selectiveCredential.Claim { 215 | fmt.Printf("Key is: %s, Value is: %s \n", k, v.Bytes()) 216 | } 217 | res, err := credentialScheme.Verify(selectiveCredential, nil, pk) 218 | if err != nil { 219 | panic(err) 220 | } 221 | fmt.Println("Verify selective credential result:", res) 222 | fmt.Println("-----------Anonymous Credential end-------------") 223 | } 224 | -------------------------------------------------------------------------------- /proof/credentials/ringers17_test.go: -------------------------------------------------------------------------------- 1 | package credentials 2 | 3 | import ( 4 | "fmt" 5 | "math/big" 6 | "scrypto/dsa/ringers17" 7 | "testing" 8 | "time" 9 | ) 10 | 11 | func TestRingersCredential_ProverKeyGen(t *testing.T) { 12 | ringersCredential := NewRingersCredential() 13 | sk, pk, err := ringersCredential.ProverKeyGen() 14 | if err != nil { 15 | panic(err) 16 | } 17 | fmt.Println("sk:", sk) 18 | fmt.Println("pk:", pk) 19 | } 20 | 21 | func TestRingersCredential_Issue(t *testing.T) { 22 | ringersSigner := ringers17.NewSigOfRingers() 23 | sks, _, err := ringersSigner.KeyGen(5) 24 | ringersCredential := NewRingersCredential() 25 | claim := make(map[string]*big.Int) 26 | claim["name"] = new(big.Int).SetBytes([]byte("Sher")) 27 | claim["identityNumber"] = new(big.Int).SetBytes([]byte("1995-05-09")) 28 | credential, err := ringersCredential.Issue(claim, sks) 29 | if err != nil { 30 | panic(err) 31 | } 32 | fmt.Println("credential:", credential) 33 | } 34 | 35 | func TestRingersCredential_ShowCredential(t *testing.T) { 36 | ringersSigner := ringers17.NewSigOfRingers() 37 | sks, _, err := ringersSigner.KeyGen(5) 38 | ringersCredential := NewRingersCredential() 39 | _, pk, err := ringersCredential.ProverKeyGen() 40 | if err != nil { 41 | panic(err) 42 | } 43 | claim := make(map[string]*big.Int) 44 | claim["name"] = new(big.Int).SetBytes([]byte("Sher")) 45 | claim["identityNumber"] = new(big.Int).SetBytes([]byte("1995-05-09")) 46 | credential, err := ringersCredential.Issue(claim, sks) 47 | if err != nil { 48 | panic(err) 49 | } 50 | fmt.Println("credential:", credential) 51 | C := make(map[string]bool) 52 | C["identityNumber"] = true 53 | selectiveCredential, err := ringersCredential.ShowCredential(credential, pk, C) 54 | if err != nil { 55 | panic(err) 56 | } 57 | fmt.Println("selective credential:", selectiveCredential) 58 | } 59 | 60 | func TestRingersCredential_Verify(t *testing.T) { 61 | ringersSigner := ringers17.NewSigOfRingers() 62 | sks, ringersPk, err := ringersSigner.KeyGen(5) 63 | ringersCredential := NewRingersCredential() 64 | _, pk, err := ringersCredential.ProverKeyGen() 65 | if err != nil { 66 | panic(err) 67 | } 68 | claim := make(map[string]*big.Int) 69 | claim["name"] = new(big.Int).SetBytes([]byte("Sher")) 70 | claim["identityNumber"] = new(big.Int).SetBytes([]byte("1995-05-09")) 71 | credential, err := ringersCredential.Issue(claim, sks) 72 | if err != nil { 73 | panic(err) 74 | } 75 | // 验证原始凭证 76 | res, err := ringersCredential.Verify(credential, nil, ringersPk) 77 | if err != nil { 78 | panic(err) 79 | } 80 | fmt.Println("原始凭证验证结果: ", res) 81 | C := make(map[string]bool) 82 | C["identityNumber"] = true 83 | selectiveCredential, err := ringersCredential.ShowCredential(credential, pk, C) 84 | if err != nil { 85 | panic(err) 86 | } 87 | // 验证子凭证 88 | res, err = ringersCredential.Verify(selectiveCredential, nil, ringersPk) 89 | if err != nil { 90 | panic(err) 91 | } 92 | fmt.Println("子凭证验证结果: ", res) 93 | } 94 | 95 | func TestTryOnce(t *testing.T) { 96 | TryOnce() 97 | } 98 | 99 | // 测试隐藏属性的性能 100 | func BenchmarkRingersCredential_Issue(b *testing.B) { 101 | b.N = 20 102 | generateTime := int64(0) 103 | issueTime := int64(0) 104 | b.ResetTimer() 105 | for i := 0; i < b.N; i++ { 106 | ringersSigner := ringers17.NewSigOfRingers() 107 | t1 := time.Now() // get current time 108 | sks, _, err := ringersSigner.KeyGen(100) 109 | elapsed := time.Since(t1) 110 | generateTime = generateTime + elapsed.Milliseconds() 111 | ringersCredential := NewRingersCredential() 112 | t2 := time.Now() // get current time 113 | // 大属性集 114 | claim := make(map[string]*big.Int) 115 | claim["1"] = new(big.Int).SetUint64(1) 116 | claim["2"] = new(big.Int).SetUint64(2) 117 | claim["3"] = new(big.Int).SetUint64(3) 118 | claim["4"] = new(big.Int).SetUint64(4) 119 | claim["5"] = new(big.Int).SetUint64(5) 120 | claim["6"] = new(big.Int).SetUint64(6) 121 | claim["7"] = new(big.Int).SetUint64(7) 122 | claim["8"] = new(big.Int).SetUint64(8) 123 | claim["9"] = new(big.Int).SetUint64(9) 124 | claim["10"] = new(big.Int).SetUint64(10) 125 | claim["11"] = new(big.Int).SetUint64(11) 126 | claim["12"] = new(big.Int).SetUint64(12) 127 | claim["13"] = new(big.Int).SetUint64(13) 128 | claim["14"] = new(big.Int).SetUint64(14) 129 | claim["15"] = new(big.Int).SetUint64(15) 130 | _, err = ringersCredential.Issue(claim, sks) 131 | elapsed = time.Since(t2) 132 | issueTime += elapsed.Milliseconds() 133 | if err != nil { 134 | panic(err) 135 | } 136 | } 137 | fmt.Println("生成100把密钥的平均时间(ms):", generateTime/int64(b.N)) 138 | fmt.Println("颁发15个属性凭证的平均时间(ms):", issueTime/int64(b.N)) 139 | } 140 | 141 | func BenchmarkRingersCredential_ShowCredential(b *testing.B) { 142 | b.N = 20 143 | showTime := int64(0) 144 | b.ResetTimer() 145 | for i := 0; i < b.N; i++ { 146 | ringersSigner := ringers17.NewSigOfRingers() 147 | sks, _, err := ringersSigner.KeyGen(50) 148 | ringersCredential := NewRingersCredential() 149 | _, pk, _ := ringersCredential.ProverKeyGen() 150 | // 大属性集 151 | claim := make(map[string]*big.Int) 152 | claim["1"] = new(big.Int).SetUint64(1) 153 | claim["2"] = new(big.Int).SetUint64(2) 154 | claim["3"] = new(big.Int).SetUint64(3) 155 | claim["4"] = new(big.Int).SetUint64(4) 156 | claim["5"] = new(big.Int).SetUint64(5) 157 | claim["6"] = new(big.Int).SetUint64(6) 158 | claim["7"] = new(big.Int).SetUint64(7) 159 | claim["8"] = new(big.Int).SetUint64(8) 160 | claim["9"] = new(big.Int).SetUint64(9) 161 | claim["10"] = new(big.Int).SetUint64(10) 162 | claim["11"] = new(big.Int).SetUint64(11) 163 | claim["12"] = new(big.Int).SetUint64(12) 164 | claim["13"] = new(big.Int).SetUint64(13) 165 | claim["14"] = new(big.Int).SetUint64(14) 166 | claim["15"] = new(big.Int).SetUint64(15) 167 | credential, err := ringersCredential.Issue(claim, sks) 168 | if err != nil { 169 | panic(err) 170 | } 171 | t1 := time.Now() 172 | C := make(map[string]bool) 173 | C["1"] = true 174 | C["2"] = true 175 | C["3"] = true 176 | C["4"] = true 177 | C["5"] = true 178 | C["6"] = true 179 | C["7"] = true 180 | C["8"] = true 181 | C["9"] = true 182 | C["10"] = true 183 | ringersCredential.ShowCredential(credential, pk, C) 184 | elapsed := time.Since(t1) 185 | showTime += elapsed.Milliseconds() 186 | } 187 | fmt.Println("隐藏10个属性的平均时间(ms):", showTime/int64(b.N)) 188 | } 189 | 190 | // 测试验证原始凭证性能 191 | func BenchmarkRingersCredential_Verify(b *testing.B) { 192 | b.N = 20 193 | verifyOriginTime := int64(0) 194 | b.ResetTimer() 195 | for i := 0; i < b.N; i++ { 196 | ringersSigner := ringers17.NewSigOfRingers() 197 | sks, ringersPk, err := ringersSigner.KeyGen(50) 198 | ringersCredential := NewRingersCredential() 199 | // 大属性集 200 | claim := make(map[string]*big.Int) 201 | claim["1"] = new(big.Int).SetUint64(1) 202 | claim["2"] = new(big.Int).SetUint64(2) 203 | claim["3"] = new(big.Int).SetUint64(3) 204 | claim["4"] = new(big.Int).SetUint64(4) 205 | claim["5"] = new(big.Int).SetUint64(5) 206 | claim["6"] = new(big.Int).SetUint64(6) 207 | claim["7"] = new(big.Int).SetUint64(7) 208 | claim["8"] = new(big.Int).SetUint64(8) 209 | claim["9"] = new(big.Int).SetUint64(9) 210 | claim["10"] = new(big.Int).SetUint64(10) 211 | claim["11"] = new(big.Int).SetUint64(11) 212 | claim["12"] = new(big.Int).SetUint64(12) 213 | claim["13"] = new(big.Int).SetUint64(13) 214 | claim["14"] = new(big.Int).SetUint64(14) 215 | claim["15"] = new(big.Int).SetUint64(15) 216 | credential, err := ringersCredential.Issue(claim, sks) 217 | if err != nil { 218 | panic(err) 219 | } 220 | t1 := time.Now() 221 | ringersCredential.Verify(credential, nil, ringersPk) 222 | elapsed := time.Since(t1) 223 | verifyOriginTime += elapsed.Milliseconds() 224 | } 225 | fmt.Println("验证15个属性集凭证的平均时间(ms),不含零知识证明: ", verifyOriginTime/int64(b.N)) 226 | } 227 | 228 | // 测试验证子凭证的性能 229 | func BenchmarkRingersCredential_Verify2(b *testing.B) { 230 | b.N = 20 231 | verifyTime := int64(0) 232 | b.ResetTimer() 233 | for i := 0; i < b.N; i++ { 234 | ringersSigner := ringers17.NewSigOfRingers() 235 | sks, ringersPk, err := ringersSigner.KeyGen(50) 236 | ringersCredential := NewRingersCredential() 237 | _, pk, _ := ringersCredential.ProverKeyGen() 238 | // 大属性集 239 | claim := make(map[string]*big.Int) 240 | claim["1"] = new(big.Int).SetUint64(1) 241 | claim["2"] = new(big.Int).SetUint64(2) 242 | claim["3"] = new(big.Int).SetUint64(3) 243 | claim["4"] = new(big.Int).SetUint64(4) 244 | claim["5"] = new(big.Int).SetUint64(5) 245 | claim["6"] = new(big.Int).SetUint64(6) 246 | claim["7"] = new(big.Int).SetUint64(7) 247 | claim["8"] = new(big.Int).SetUint64(8) 248 | claim["9"] = new(big.Int).SetUint64(9) 249 | claim["10"] = new(big.Int).SetUint64(10) 250 | claim["11"] = new(big.Int).SetUint64(11) 251 | claim["12"] = new(big.Int).SetUint64(12) 252 | claim["13"] = new(big.Int).SetUint64(13) 253 | claim["14"] = new(big.Int).SetUint64(14) 254 | claim["15"] = new(big.Int).SetUint64(15) 255 | credential, err := ringersCredential.Issue(claim, sks) 256 | if err != nil { 257 | panic(err) 258 | } 259 | C := make(map[string]bool) 260 | C["1"] = true 261 | C["2"] = true 262 | C["3"] = true 263 | C["4"] = true 264 | C["5"] = true 265 | C["6"] = true 266 | C["7"] = true 267 | C["8"] = true 268 | C["9"] = true 269 | C["10"] = true 270 | selectiveCredential, err := ringersCredential.ShowCredential(credential, pk, C) 271 | if err != nil { 272 | panic(err) 273 | } 274 | t1 := time.Now() 275 | ringersCredential.Verify(selectiveCredential, nil, ringersPk) 276 | elapsed := time.Since(t1) 277 | verifyTime += elapsed.Milliseconds() 278 | } 279 | fmt.Println("验证15个属性隐藏10个属性的凭证平均耗时(ms),含零知识证明:", verifyTime/int64(b.N)) 280 | } 281 | -------------------------------------------------------------------------------- /proof/sigmaProtocol/README.md: -------------------------------------------------------------------------------- 1 | # Schnorr Non-interactive Zero-Knowledge Proof 2 | 3 | ## Img 4 | 5 | ![NIZK](assets/NIZK.png) 6 | 7 | ## Origin 8 | 9 | We assume that there are $2$ users: Alice(Prover), Bob(Verifier) 10 | 11 | $Setup(1^{\lambda}) \rightarrow{} (G,g,p)$: 12 | 13 | $G$ is a group define over finite domain $Z_p $, $g \in G$ is the generator of the group and $p$ is the prime order of the group 14 | 15 | $Prove(x,v) \rightarrow{} (X,V,r)$: 16 | 17 | Alice executes this algorithm. The input $x$ is Alice's secret and $v \in_R Z_p$ 18 | $$ 19 | X := g^{x} \\ 20 | V := g^{v} \\ 21 | c := H(g \| X \| V), \text{H is a collision-resistant hash functions: such as sha256} \\ 22 | r := v - cx 23 | $$ 24 | Then Alice sends $X,V,r$ to Bob(Verifier). 25 | 26 | $Verify(X,V,r) \rightarrow{} 1/0$: 27 | 28 | Bob executes this algorithm. These input parameters were passed by Alice. 29 | $$ 30 | c := H(g \| X \| V) \\ 31 | \text{check if } V \overset{?}{=} g^r X^c \\ 32 | Verify: g^r X^c = g^{v-cx} g^{cx} = g^{v -cx +cx} = g^v = V 33 | $$ 34 | 35 | # References 36 | 37 | https://tools.ietf.org/html/rfc8235 -------------------------------------------------------------------------------- /proof/sigmaProtocol/assets/NIZK.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherLzp/scrypto/60ae416361d692ba2c7a57b8cccd87b1c30995f8/proof/sigmaProtocol/assets/NIZK.png -------------------------------------------------------------------------------- /proof/sigmaProtocol/sigmaNIZK.go: -------------------------------------------------------------------------------- 1 | package sigmaProtocol 2 | 3 | import ( 4 | "crypto/rand" 5 | "encoding/hex" 6 | "encoding/json" 7 | "errors" 8 | "fmt" 9 | "golang.org/x/crypto/bn256" 10 | "math/big" 11 | "scrypto/ecc/bn256Utils" 12 | sherMath "scrypto/smath" 13 | "scrypto/sutils" 14 | "strings" 15 | ) 16 | 17 | type sigmaNIZK struct { 18 | Pairs []*Pair 19 | P *big.Int 20 | } 21 | 22 | func NewSigmaNIZK(p *big.Int) (nizk *sigmaNIZK) { 23 | nizk = &sigmaNIZK{ 24 | P: p, 25 | } 26 | return nizk 27 | } 28 | 29 | type Pair struct { 30 | Secret *big.Int 31 | Public *bn256.G1 32 | } 33 | 34 | type ProveScheme struct { 35 | Commitment *bn256.G1 `json:"Commitment"` 36 | Challenge *big.Int `json:"Challenge"` 37 | Proofs []*big.Int `json:"Proofs"` 38 | PubValues []*bn256.G1 `json:"PubValues"` 39 | Relation *bn256.G1 `json:"Relation"` 40 | Owner *bn256.G1 `json:"Owner"` 41 | } 42 | 43 | const ( 44 | ProveScheme_Commitment = "Commitment" 45 | ProveScheme_Challenge = "Challenge" 46 | ProveScheme_Proofs = "Proofs" 47 | ProveScheme_PubValues = "PubValues" 48 | ProveScheme_Relation = "Relation" 49 | ProveScheme_Owner = "Owner" 50 | ) 51 | 52 | // serialize scheme 53 | func (scheme *ProveScheme) MarshalJSON() ([]byte, error) { 54 | kv := make(map[string]string) 55 | // Commitment 56 | kv[ProveScheme_Commitment] = hex.EncodeToString(scheme.Commitment.Marshal()) 57 | // Challenge 58 | kv[ProveScheme_Challenge] = hex.EncodeToString(scheme.Challenge.Bytes()) 59 | // Proofs 60 | var proofsSlice []string 61 | for _, v := range scheme.Proofs { 62 | proof := hex.EncodeToString(v.Bytes()) 63 | proofsSlice = append(proofsSlice, proof) 64 | } 65 | proofsStr := strings.Join(proofsSlice, ",") 66 | kv[ProveScheme_Proofs] = proofsStr 67 | // PubValues 68 | var pubValuesSlice []string 69 | for _, v := range scheme.PubValues { 70 | pubValue := hex.EncodeToString(v.Marshal()) 71 | pubValuesSlice = append(pubValuesSlice, pubValue) 72 | } 73 | pubValuesStr := strings.Join(pubValuesSlice, ",") 74 | kv[ProveScheme_PubValues] = pubValuesStr 75 | // Relation 76 | kv[ProveScheme_Relation] = hex.EncodeToString(scheme.Relation.Marshal()) 77 | // Owner 78 | kv[ProveScheme_Owner] = hex.EncodeToString(scheme.Owner.Marshal()) 79 | return json.Marshal(kv) 80 | } 81 | 82 | // deserialize scheme 83 | func (scheme *ProveScheme) UnmarshalJSON(data []byte) error { 84 | // get kv first 85 | kv := make(map[string]string) 86 | err := json.Unmarshal(data, &kv) 87 | if err != nil { 88 | return err 89 | } 90 | // get attributes of ProveScheme 91 | // Commitment 92 | CommitmentBytes, err := hex.DecodeString(kv[ProveScheme_Commitment]) 93 | // Challenge 94 | ChallengeBytes, err := hex.DecodeString(kv[ProveScheme_Challenge]) 95 | if err != nil { 96 | return err 97 | } 98 | Commitment, res := new(bn256.G1).Unmarshal(CommitmentBytes) 99 | if !res { 100 | return errors.New("error when unmarshal G1 of CommitmentBytes") 101 | } 102 | scheme.Commitment = Commitment 103 | Challenge := new(big.Int).SetBytes(ChallengeBytes) 104 | scheme.Challenge = Challenge 105 | // Proofs 106 | proofsSlice := strings.Split(kv[ProveScheme_Proofs], ",") 107 | for _, v := range proofsSlice { 108 | ProofBytes, err := hex.DecodeString(v) 109 | if err != nil { 110 | return err 111 | } 112 | Proof := new(big.Int).SetBytes(ProofBytes) 113 | scheme.Proofs = append(scheme.Proofs, Proof) 114 | } 115 | // PubValues 116 | pubValuesSlice := strings.Split(kv[ProveScheme_PubValues], ",") 117 | for _, v := range pubValuesSlice { 118 | pubValueBytes, err := hex.DecodeString(v) 119 | if err != nil { 120 | return err 121 | } 122 | pubValue, res := new(bn256.G1).Unmarshal(pubValueBytes) 123 | if !res { 124 | return errors.New("error when unmarshal G1 of PubValueBytes") 125 | } 126 | scheme.PubValues = append(scheme.PubValues, pubValue) 127 | } 128 | // Relation 129 | RelationBytes, err := hex.DecodeString(kv[ProveScheme_Relation]) 130 | // Owner 131 | OwnerBytes, err := hex.DecodeString(kv[ProveScheme_Owner]) 132 | Relation, res := new(bn256.G1).Unmarshal(RelationBytes) 133 | if !res { 134 | return errors.New("error when unmarshal G1 of RelationBytes") 135 | } 136 | Owner, res := new(bn256.G1).Unmarshal(OwnerBytes) 137 | if !res { 138 | return errors.New("error when unmarshal G1 of OwnerBytes") 139 | } 140 | scheme.Relation = Relation 141 | scheme.Owner = Owner 142 | return nil 143 | } 144 | 145 | func (this *sigmaNIZK) AddPair(secret *big.Int, public *bn256.G1) { 146 | pair := &Pair{ 147 | Secret: secret, 148 | Public: public, 149 | } 150 | this.Pairs = append(this.Pairs, pair) 151 | } 152 | 153 | func (this *sigmaNIZK) Prove(R *bn256.G1, pk *bn256.G1, optionData []byte) (prove *ProveScheme, err error) { 154 | pairs := this.Pairs 155 | if len(pairs) <= 0 { 156 | return nil, errors.New("claim count should larger than 0") 157 | } 158 | prove = new(ProveScheme) 159 | // R = \prod (pairs[i].Secret)^{pairs[i].Public} 160 | secretCount := len(pairs) 161 | // generate random numbers 162 | rs := make([]*big.Int, secretCount) 163 | rs[0], _ = rand.Int(rand.Reader, this.P) 164 | t := bn256Utils.G1ScalarMult(pairs[0].Public, rs[0]) 165 | for i := 1; i < secretCount; i++ { 166 | rs[i], _ = rand.Int(rand.Reader, this.P) 167 | // t_i = (pairs[i].Public)^{randNums[i]} 168 | // t = \prod t_i 169 | ti := bn256Utils.G1ScalarMult(pairs[i].Public, rs[i]) 170 | t = bn256Utils.G1Add(t, ti) 171 | } 172 | // c = H(g || t || A || optionData) 173 | base := bn256Utils.G1ScalarBaseMult(new(big.Int).SetInt64(1)) 174 | cPre := sutils.ContactBytes(base.Marshal(), t.Marshal(), pk.Marshal(), optionData) 175 | c, err := sutils.GetSha3HashBytes(cPre) 176 | if err != nil { 177 | return nil, err 178 | } 179 | cInt := new(big.Int).SetBytes(c) 180 | for i := 0; i < secretCount; i++ { 181 | // si = ri - c secret 182 | c_secret := sherMath.Mul(cInt, pairs[i].Secret, this.P) 183 | si := sherMath.Sub(rs[i], c_secret, this.P) 184 | prove.Proofs = append(prove.Proofs, si) 185 | prove.PubValues = append(prove.PubValues, pairs[i].Public) 186 | } 187 | prove.Challenge = cInt 188 | prove.Commitment = t 189 | prove.Relation = R 190 | prove.Owner = pk 191 | return prove, nil 192 | } 193 | 194 | func (this *sigmaNIZK) Verify(prove *ProveScheme, optionData []byte) (res bool, err error) { 195 | if len(prove.Proofs) != len(prove.PubValues) { 196 | return false, nil 197 | } 198 | // check t == (pubValue)^{s[i]} * R^c 199 | tVer := bn256Utils.G1ScalarMult(prove.Relation, prove.Challenge) 200 | keyCount := len(prove.PubValues) 201 | ss := prove.Proofs 202 | pubValues := prove.PubValues 203 | for i := 0; i < keyCount; i++ { 204 | pubValue_si := bn256Utils.G1ScalarMult(pubValues[i], ss[i]) 205 | tVer = bn256Utils.G1Add(tVer, pubValue_si) 206 | } 207 | res = prove.Commitment.String() == tVer.String() 208 | return res, nil 209 | } 210 | 211 | func TryOnce() { 212 | fmt.Println("-----------Sigma NIZK start-------------") 213 | //optionData := []byte("Hello NIZK") 214 | 215 | a, A, err := bn256.RandomG1(rand.Reader) 216 | if err != nil { 217 | panic(err) 218 | } 219 | base := bn256Utils.G1ScalarBaseMult(new(big.Int).SetInt64(1)) 220 | nizk := NewSigmaNIZK(bn256.Order) 221 | nizk.AddPair(a, base) 222 | prove, err := nizk.Prove(A, A, nil) 223 | if err != nil { 224 | panic(err) 225 | } 226 | fmt.Println("prove scheme:", prove) 227 | res, err := nizk.Verify(prove, nil) 228 | if err != nil { 229 | panic(err) 230 | } 231 | fmt.Println("Verify result:", res) 232 | fmt.Println("-----------Sigma NIZK end-------------") 233 | } 234 | -------------------------------------------------------------------------------- /proof/sigmaProtocol/sigmaNIZK_test.go: -------------------------------------------------------------------------------- 1 | package sigmaProtocol 2 | 3 | import ( 4 | "crypto/rand" 5 | "fmt" 6 | "golang.org/x/crypto/bn256" 7 | "math/big" 8 | "scrypto/ecc/bn256Utils" 9 | "testing" 10 | ) 11 | 12 | func TestSchnorrNIZK_Prove(t *testing.T) { 13 | nizk := NewSigmaNIZK(bn256.Order) 14 | // we generate prove: A = g^{a} 15 | base := bn256Utils.G1ScalarBaseMult(new(big.Int).SetInt64(1)) 16 | a, A, err := bn256.RandomG1(rand.Reader) 17 | fmt.Println("Alice public key and proof relation: ", A.String()) 18 | if err != nil { 19 | panic(err) 20 | } 21 | nizk.AddPair(a, base) 22 | prove, err := nizk.Prove(A, A, nil) 23 | if err != nil { 24 | panic(err) 25 | } 26 | fmt.Println("Prove owner:", prove.Owner.String()) 27 | fmt.Println("Prove s.t.:", prove.Relation.String()) 28 | fmt.Println("Prove commitment:", prove.Commitment) 29 | } 30 | 31 | func TestSchnorrNIZK_Verify(t *testing.T) { 32 | nizk := NewSigmaNIZK(bn256.Order) 33 | // we generate prove: A = g^{a} 34 | base := bn256Utils.G1ScalarBaseMult(new(big.Int).SetInt64(1)) 35 | a, A, err := bn256.RandomG1(rand.Reader) 36 | fmt.Println("Alice public key and proof relation: ", A.String()) 37 | if err != nil { 38 | panic(err) 39 | } 40 | nizk.AddPair(a, base) 41 | prove, err := nizk.Prove(A, A, nil) 42 | if err != nil { 43 | panic(err) 44 | } 45 | fmt.Println("Prove owner:", prove.Owner.String()) 46 | fmt.Println("Prove s.t.:", prove.Relation.String()) 47 | fmt.Println("Prove commitment:", prove.Commitment) 48 | prove.Relation = A 49 | res, err := nizk.Verify(prove, nil) 50 | if err != nil { 51 | panic(err) 52 | } 53 | fmt.Println("Verify result:", res) 54 | 55 | } 56 | -------------------------------------------------------------------------------- /shash/merkleTree/merkleTree.go: -------------------------------------------------------------------------------- 1 | package merkleTree 2 | 3 | import ( 4 | "bytes" 5 | "crypto/sha256" 6 | "errors" 7 | "fmt" 8 | "hash" 9 | "scrypto/sutils" 10 | ) 11 | 12 | type MerkleTree struct { 13 | Root *Node // Root node of Merkle Tree 14 | Leaves []*Node // Leaves 15 | hashStrategy func() hash.Hash // hash function 16 | rootHash []byte // root node hash value 17 | } 18 | 19 | type Node struct { 20 | Parent *Node // parent node 21 | Left *Node // left node 22 | Right *Node // right node 23 | leaf bool // is leaf or not 24 | dup bool // is duplicate node or not 25 | HashVal []byte // hash value of the node 26 | } 27 | 28 | //NewTree creates a new Merkle Tree using the bytes vector. 29 | func NewTree(values [][]byte) (t *MerkleTree, err error) { 30 | var defaultHashStrategy = sha256.New 31 | t = &MerkleTree{ 32 | hashStrategy: defaultHashStrategy, 33 | } 34 | root, leaves, err := buildWithValues(values, t) 35 | if err != nil { 36 | return nil, err 37 | } 38 | t.Root = root 39 | t.Leaves = leaves 40 | t.rootHash = root.HashVal 41 | return t, nil 42 | } 43 | 44 | func buildWithValues(values [][]byte, t *MerkleTree) (root *Node, leaves []*Node, err error) { 45 | if len(values) == 0 { 46 | return nil, nil, errors.New("error: cannot construct shash with no values") 47 | } 48 | for _, val := range values { 49 | h := t.hashStrategy 50 | hashVal, err := sutils.GetHashValue(val, h) 51 | if err != nil { 52 | return nil, nil, err 53 | } 54 | leaves = append(leaves, &Node{ 55 | HashVal: hashVal, 56 | leaf: true, 57 | }) 58 | } 59 | 60 | if len(leaves)%2 == 1 { 61 | duplicate := &Node{ 62 | HashVal: leaves[len(leaves)-1].HashVal, 63 | leaf: true, 64 | dup: true, 65 | } 66 | leaves = append(leaves, duplicate) 67 | } 68 | 69 | root, err = buildIntermediate(leaves, t) 70 | if err != nil { 71 | return nil, nil, err 72 | } 73 | 74 | return root, leaves, nil 75 | } 76 | 77 | func buildIntermediate(nodes []*Node, t *MerkleTree) (root *Node, err error) { 78 | var newNodes []*Node 79 | for i := 0; i < len(nodes); i += 2 { 80 | left, right := i, i+1 81 | if i+1 == len(nodes) { 82 | right = i 83 | } 84 | chash := append(nodes[left].HashVal, nodes[right].HashVal...) 85 | h := t.hashStrategy 86 | hashVal, err := sutils.GetHashValue(chash, h) 87 | if err != nil { 88 | return nil, err 89 | } 90 | node := &Node{ 91 | Left: nodes[left], 92 | Right: nodes[right], 93 | HashVal: hashVal, 94 | } 95 | newNodes = append(newNodes, node) 96 | nodes[left].Parent = node 97 | nodes[right].Parent = node 98 | if len(nodes) == 2 { 99 | return node, nil 100 | } 101 | } 102 | return buildIntermediate(newNodes, t) 103 | } 104 | 105 | //MerkleRoot returns the unverified Merkle Root (hash of the root node) of the shash. 106 | func (mt *MerkleTree) MerkleRoot() []byte { 107 | return mt.rootHash 108 | } 109 | 110 | func NewTreeWithHashStrategy(values [][]byte, hashStrategy func() hash.Hash) (*MerkleTree, error) { 111 | t := &MerkleTree{ 112 | hashStrategy: hashStrategy, 113 | } 114 | root, leaves, err := buildWithValues(values, t) 115 | if err != nil { 116 | return nil, err 117 | } 118 | t.Root = root 119 | t.Leaves = leaves 120 | t.rootHash = root.HashVal 121 | return t, nil 122 | } 123 | 124 | // GetMerklePath: Get Merkle path and indexes(left leaf or right leaf) 125 | func (mt *MerkleTree) GetMerklePath(value []byte) (merklePath [][]byte, index []int64, err error) { 126 | for _, node := range mt.Leaves { 127 | h := mt.hashStrategy 128 | hashVal, err := sutils.GetHashValue(value, h) 129 | if err != nil { 130 | return nil, nil, err 131 | } 132 | 133 | if bytes.Equal(node.HashVal, hashVal) { 134 | nodeParent := node.Parent 135 | for nodeParent != nil { 136 | if bytes.Equal(nodeParent.Left.HashVal, node.HashVal) { 137 | merklePath = append(merklePath, nodeParent.Right.HashVal) 138 | index = append(index, 1) // right leaf 139 | } else { 140 | merklePath = append(merklePath, nodeParent.Left.HashVal) 141 | index = append(index, 0) // left leaf 142 | } 143 | node = nodeParent 144 | nodeParent = nodeParent.Parent 145 | } 146 | return merklePath, index, nil 147 | } 148 | } 149 | return nil, nil, nil 150 | } 151 | 152 | func (mt *MerkleTree) VerifyValue(value []byte) (bool, error) { 153 | for _, node := range mt.Leaves { 154 | h := mt.hashStrategy 155 | hashVal, err := sutils.GetHashValue(value, h) 156 | if err != nil { 157 | return false, err 158 | } 159 | 160 | if bytes.Equal(node.HashVal, hashVal) { 161 | nodeParent := node.Parent 162 | for nodeParent != nil { 163 | leftBytes := nodeParent.Left.HashVal 164 | rightBytes := nodeParent.Right.HashVal 165 | cBytes := append(leftBytes, rightBytes...) 166 | cHashVal, err := sutils.GetHashValue(cBytes, h) 167 | if err != nil { 168 | return false, err 169 | } 170 | if !bytes.Equal(cHashVal, nodeParent.HashVal) { 171 | return false, nil 172 | } 173 | nodeParent = nodeParent.Parent 174 | } 175 | return true, nil 176 | } 177 | } 178 | return false, nil 179 | } 180 | 181 | //String returns a string representation of the node. 182 | func (n *Node) String() string { 183 | return fmt.Sprintf("%t %t %v", n.leaf, n.dup, n.HashVal) 184 | } 185 | 186 | //String returns a string representation of the shash. Only leaf nodes are included 187 | //in the output. 188 | func (mt *MerkleTree) String() string { 189 | s := "" 190 | for _, l := range mt.Leaves { 191 | s += fmt.Sprint(l) 192 | s += "\n" 193 | } 194 | return s 195 | } 196 | -------------------------------------------------------------------------------- /shash/merkleTree/merkleTree_test.go: -------------------------------------------------------------------------------- 1 | package merkleTree 2 | 3 | import ( 4 | "crypto/sha256" 5 | "fmt" 6 | "shercrypto/xutils" 7 | "testing" 8 | ) 9 | 10 | var ( 11 | name = []byte("name") 12 | age = []byte("age") 13 | identity = []byte("identity") 14 | values = [][]byte{name, age, identity} 15 | ) 16 | // Tree 17 | // h(h(1,2),h(3,4)) 18 | // h(1,2) h(3,4) 19 | //h(name) h(age) h(identity) h(identity) 20 | //1 2 3 4 21 | 22 | func TestNewTree(t *testing.T) { 23 | ageBytes, _ := xutils.GetHashValue(age, sha256.New) 24 | fmt.Println("ageBytes:", ageBytes) 25 | tree, err := NewTree(values) 26 | if err != nil { 27 | panic(err) 28 | } 29 | fmt.Println("Leaves:", tree.Leaves) 30 | 31 | } 32 | 33 | func TestMerkleTree_GetMerklePath(t *testing.T) { 34 | tree, err := NewTree(values) 35 | if err != nil { 36 | panic(err) 37 | } 38 | merklePath, index, err := tree.GetMerklePath(name) 39 | if err != nil { 40 | panic(err) 41 | } 42 | fmt.Println("Merkle Path:", merklePath) 43 | fmt.Println("index:", index) 44 | } 45 | 46 | func TestMerkleTree_VerifyValue(t *testing.T) { 47 | tree, err := NewTree(values) 48 | if err != nil { 49 | panic(err) 50 | } 51 | isValid, err := tree.VerifyValue(age) 52 | if err != nil { 53 | panic(err) 54 | } 55 | fmt.Println("is valid value:", isValid) 56 | } 57 | -------------------------------------------------------------------------------- /smath/smath.go: -------------------------------------------------------------------------------- 1 | package smath 2 | 3 | import "math/big" 4 | 5 | func Add(a, b, N *big.Int) (res *big.Int) { 6 | res = new(big.Int).Add(a, b) 7 | res.Mod(res, N) 8 | return res 9 | } 10 | 11 | func Sub(a, b, N *big.Int) (res *big.Int) { 12 | res = new(big.Int).Sub(a, b) 13 | res.Mod(res, N) 14 | return res 15 | } 16 | 17 | func Mul(a, b, N *big.Int) (res *big.Int) { 18 | res = new(big.Int).Mul(a, b) 19 | res.Mod(res, N) 20 | return res 21 | } 22 | 23 | func ModInverse(a, N *big.Int) (res *big.Int) { 24 | res = new(big.Int).ModInverse(a, N) 25 | return res 26 | } 27 | 28 | func Neg(a *big.Int) (res *big.Int) { 29 | return new(big.Int).Neg(a) 30 | } 31 | -------------------------------------------------------------------------------- /sutils/hashUtils.go: -------------------------------------------------------------------------------- 1 | package sutils 2 | 3 | import ( 4 | "crypto/elliptic" 5 | "crypto/rand" 6 | "crypto/sha256" 7 | "encoding/hex" 8 | "hash" 9 | "math/big" 10 | "scrypto/ecc/p256Utils" 11 | ) 12 | 13 | /** 14 | 计算SHA3哈希值 15 | */ 16 | func GetSha3HashBytes(m []byte) (hash []byte, err error) { 17 | sha := sha256.New() 18 | _, err = sha.Write(m) 19 | if err != nil { 20 | return nil, err 21 | } 22 | return sha.Sum(nil), nil 23 | } 24 | 25 | /** 26 | 计算哈希值 27 | */ 28 | func GetHashValue(m []byte, hFunction func() hash.Hash) ([]byte, error) { 29 | h := hFunction() 30 | _, err := h.Write(m) 31 | if err != nil { 32 | return nil, err 33 | } 34 | return h.Sum(nil), nil 35 | } 36 | 37 | /** 38 | 计算SHA3哈希值并转换为字符串 39 | */ 40 | func GetSha3HashStr(m string) (hash string, err error) { 41 | hashBytes, err := GetSha3HashBytes([]byte(m)) 42 | if err != nil { 43 | return "", err 44 | } 45 | hash = hex.EncodeToString(hashBytes) 46 | return hash, nil 47 | } 48 | 49 | /** 50 | 计算单个值的Pedersen承诺 51 | */ 52 | func ComputeCommitmentBytes(value *big.Int) (c []byte, err error) { 53 | // c = g^m h^{\alpha} 54 | alpha, err := rand.Int(rand.Reader, elliptic.P256().Params().N) 55 | if err != nil { 56 | return nil, err 57 | } 58 | g_m := p256Utils.ScalarBaseMult(value) 59 | h_alpha := p256Utils.ScalarMult(p256Utils.ComputeH(), alpha) 60 | commitment := p256Utils.ScalarAdd(g_m, h_alpha) 61 | c = p256Utils.Marshal(commitment) 62 | return c, nil 63 | } 64 | 65 | /** 66 | 计算向量的Pedersen承诺 67 | */ 68 | func ComputeVecCommitmentBytes(values []*big.Int) (c []byte, err error) { 69 | n := len(values) 70 | gs, hs := p256Utils.ComputeGAndHVec(n) 71 | zero := new(big.Int).SetInt64(0) 72 | commitment := &p256Utils.CurvePoint{ 73 | elliptic.P256(), zero, zero, 74 | } 75 | for i := 0; i < n; i++ { 76 | alphai, err := rand.Int(rand.Reader, elliptic.P256().Params().N) 77 | if err != nil { 78 | return nil, err 79 | } 80 | gi_m := p256Utils.ScalarMult(gs[i], values[i]) 81 | hi_alpha := p256Utils.ScalarMult(hs[i], alphai) 82 | commitment_i := p256Utils.ScalarAdd(gi_m, hi_alpha) 83 | commitment = p256Utils.ScalarAdd(commitment, commitment_i) 84 | } 85 | c = p256Utils.Marshal(commitment) 86 | return c, nil 87 | } 88 | 89 | /** 90 | 计算Pedersen Commitment并转换为字符串 91 | */ 92 | func ComputeVecCommitmentStr(values []*big.Int) (c string, err error) { 93 | cBytes, err := ComputeVecCommitmentBytes(values) 94 | if err != nil { 95 | return "", err 96 | } 97 | c = hex.EncodeToString(cBytes) 98 | return c, nil 99 | } 100 | -------------------------------------------------------------------------------- /sutils/utils.go: -------------------------------------------------------------------------------- 1 | package sutils 2 | 3 | func ContactBytes(a, b []byte, in ...[]byte) (res []byte) { 4 | contact := func(_a, _b []byte) (_res []byte) { 5 | _res = append(_a, _b...) 6 | return _res 7 | } 8 | res = append(a, b...) 9 | for i := 0; i < len(in); i++ { 10 | res = contact(res, in[i]) 11 | } 12 | return res 13 | } 14 | --------------------------------------------------------------------------------