├── go.mod ├── sm ├── sm3 │ ├── sm3block_amd64.go │ ├── sm3block_arm64.go │ ├── sm3_test.go │ ├── sm3.go │ └── sm3hash.go ├── sm9 │ ├── sm9_test.go │ └── sm9.go ├── sm2 │ ├── external.go │ ├── sm2enc.go │ ├── sm2_test.go │ └── sm2.go └── sm4 │ ├── sm4_test.go │ ├── sm4.go │ └── const.go ├── .gitignore ├── elliptic ├── sm9curve │ ├── hash_test.go │ ├── gfp_decl.go │ ├── example_test.go │ ├── LICENSE │ ├── README.md │ ├── hash.go │ ├── gfp_arm64.s │ ├── mul_bmi2_amd64.h │ ├── gfp_amd64.s │ ├── mul_arm64.h │ ├── genpara │ │ └── genconsts │ │ │ ├── gfp2.go │ │ │ └── genconsts.go │ ├── mul_amd64.h │ ├── gfp.go │ ├── gfp2.go │ ├── gfp_generic.go │ ├── constants.go │ ├── twist.go │ ├── curve.go │ ├── gfp6.go │ ├── gfp12.go │ ├── optate.go │ ├── bn256_test.go │ └── bn256.go └── sm2curve │ ├── sm2p256_arm64.go │ └── elliptic.go ├── .github └── workflows │ └── go.yml ├── go.sum ├── LICENSE └── README.md /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/xlcetc/cryptogm 2 | 3 | go 1.14 4 | 5 | require ( 6 | github.com/pkg/errors v0.9.1 7 | golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a 8 | golang.org/x/sys v0.0.0-20200821140526-fda516888d29 9 | ) 10 | -------------------------------------------------------------------------------- /sm/sm3/sm3block_amd64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 cetc-30. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build amd64 6 | 7 | package sm3 8 | 9 | //go:noescape 10 | 11 | func block(dig *digest, p []byte) 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # IntelliJ project files 2 | .idea/* 3 | .idea 4 | *.iml 5 | out 6 | 7 | # Binaries for programs and plugins 8 | *.exe 9 | *.exe~ 10 | *.dll 11 | *.so 12 | *.dylib 13 | 14 | # Test binary, build with `go test -c` 15 | *.test 16 | 17 | # Output of the go coverage tool, specifically when used with LiteIDE 18 | *.out 19 | -------------------------------------------------------------------------------- /sm/sm3/sm3block_arm64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 cetc-30. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build arm64 6 | // +build arm64 7 | 8 | package sm3 9 | 10 | // no asm 11 | func block(dig *digest, p []byte) { 12 | Block(dig, p) 13 | } 14 | -------------------------------------------------------------------------------- /elliptic/sm9curve/hash_test.go: -------------------------------------------------------------------------------- 1 | package sm9curve 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | var buf = make([]byte, 8192) 8 | 9 | func benchmarkSize(b *testing.B, size int) { 10 | b.SetBytes(int64(size)) 11 | for i := 0; i < b.N; i++ { 12 | HashG1(buf[:size], nil) 13 | } 14 | } 15 | 16 | func BenchmarkHashG1Size8bytes(b *testing.B) { 17 | b.ResetTimer() 18 | benchmarkSize(b, 8) 19 | } 20 | 21 | func BenchmarkHashG1Size1k(b *testing.B) { 22 | b.ResetTimer() 23 | benchmarkSize(b, 1024) 24 | } 25 | 26 | func BenchmarkHashG1Size8k(b *testing.B) { 27 | b.ResetTimer() 28 | benchmarkSize(b, 8192) 29 | } 30 | -------------------------------------------------------------------------------- /elliptic/sm9curve/gfp_decl.go: -------------------------------------------------------------------------------- 1 | //go:build (amd64 && !generic) || (!arm64 && !generic) 2 | // +build amd64,!generic !arm64,!generic 3 | 4 | package sm9curve 5 | 6 | // This file contains forward declarations for the architecture-specific 7 | // assembly implementations of these functions, provided that they exist. 8 | 9 | import ( 10 | "golang.org/x/sys/cpu" 11 | ) 12 | 13 | var hasBMI2 = cpu.X86.HasBMI2 14 | 15 | // go:noescape 16 | func gfpNeg(c, a *gfP) 17 | 18 | //go:noescape 19 | func gfpAdd(c, a, b *gfP) 20 | 21 | //go:noescape 22 | func gfpSub(c, a, b *gfP) 23 | 24 | //go:noescape 25 | func gfpMul(c, a, b *gfP) 26 | -------------------------------------------------------------------------------- /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | name: Go 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | 7 | build: 8 | name: Build 9 | runs-on: ubuntu-latest 10 | steps: 11 | 12 | - name: Set up Go 1.x 13 | uses: actions/setup-go@v2 14 | with: 15 | go-version: ^1.17 16 | id: go 17 | 18 | - name: Check out code into the Go module directory 19 | uses: actions/checkout@v2 20 | 21 | - name: Get dependencies 22 | run: | 23 | go get -v -t -d ./... 24 | 25 | - name: TestSm2Curve 26 | run: go test -v ./elliptic/sm2curve/ 27 | 28 | - name: TestSm9Curve 29 | run: go test -v ./elliptic/sm9curve/ 30 | 31 | - name: TestSm2 32 | run: go test -v ./sm/sm2/ 33 | 34 | - name: TestSm3 35 | run: go test -v ./sm/sm3/ 36 | 37 | - name: TestSm4 38 | run: go test -v ./sm/sm4/ 39 | 40 | - name: TestSm9 41 | run: go test -v ./sm/sm9/ -------------------------------------------------------------------------------- /elliptic/sm2curve/sm2p256_arm64.go: -------------------------------------------------------------------------------- 1 | //go:build arm64 2 | // +build arm64 3 | 4 | package sm2curve 5 | 6 | import ( 7 | "math/big" 8 | ) 9 | 10 | type ( 11 | p256Curve struct { 12 | *CurveParams 13 | } 14 | ) 15 | 16 | var ( 17 | p256 p256Curve 18 | ) 19 | 20 | func initP256() { 21 | // See FIPS 186-3, section D.2.3 22 | p256.CurveParams = &CurveParams{Name: "P-256"} 23 | p256.P, _ = new(big.Int).SetString("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", 16) 24 | p256.N, _ = new(big.Int).SetString("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123", 16) 25 | p256.B, _ = new(big.Int).SetString("28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93", 16) 26 | p256.Gx, _ = new(big.Int).SetString("32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", 16) 27 | p256.Gy, _ = new(big.Int).SetString("BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0", 16) 28 | p256.BitSize = 256 29 | } 30 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 2 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 3 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 4 | golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM= 5 | golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 6 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 7 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 8 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 9 | golang.org/x/sys v0.0.0-20200821140526-fda516888d29 h1:mNuhGagCf3lDDm5C0376C/sxh6V7fy9WbdEu/YDNA04= 10 | golang.org/x/sys v0.0.0-20200821140526-fda516888d29/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 11 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 12 | -------------------------------------------------------------------------------- /elliptic/sm9curve/example_test.go: -------------------------------------------------------------------------------- 1 | package sm9curve 2 | 3 | import ( 4 | "crypto/rand" 5 | ) 6 | 7 | func ExamplePair() { 8 | // This implements the tripartite Diffie-Hellman algorithm from "A One 9 | // Round Protocol for Tripartite Diffie-Hellman", A. Joux. 10 | // http://www.springerlink.com/content/cddc57yyva0hburb/fulltext.pdf 11 | 12 | // Each of three parties, a, b and c, generate a private value. 13 | a, _ := rand.Int(rand.Reader, Order) 14 | b, _ := rand.Int(rand.Reader, Order) 15 | c, _ := rand.Int(rand.Reader, Order) 16 | 17 | // Then each party calculates g₁ and g₂ times their private value. 18 | pa := new(G1).ScalarBaseMult(a) 19 | qa := new(G2).ScalarBaseMult(a) 20 | 21 | pb := new(G1).ScalarBaseMult(b) 22 | qb := new(G2).ScalarBaseMult(b) 23 | 24 | pc := new(G1).ScalarBaseMult(c) 25 | qc := new(G2).ScalarBaseMult(c) 26 | 27 | // Now each party exchanges its public values with the other two and 28 | // all parties can calculate the shared key. 29 | k1 := Pair(pb, qc) 30 | k1.ScalarMult(k1, a) 31 | 32 | k2 := Pair(pc, qa) 33 | k2.ScalarMult(k2, b) 34 | 35 | k3 := Pair(pa, qb) 36 | k3.ScalarMult(k3, c) 37 | 38 | // k1, k2 and k3 will all be equal. 39 | } 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020, cetcxl. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 5 | 6 | - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 7 | - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the docume 8 | ntation and/or other materials provided with the distribution. 9 | - Neither the name of the nor the names of its contributors may be used to endorse or promote products derived from this 10 | software without specific prior written permission. 11 | 12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUD 13 | ING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN N 14 | O EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR C 15 | ONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR P 16 | ROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 17 | TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBI 18 | LITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /elliptic/sm9curve/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 The Go Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cryptogm in golang 2 | 3 | ![Go](https://github.com/xlcetc/cryptogm/workflows/Go/badge.svg?branch=master) 4 | 5 | An implementation of china crypto standards written in golang. This package includes sm2,sm3,sm4 and sm9 algorithms. 6 | Some algorithms have been optimized using AVX2 instructions. 7 | # Install 8 | 9 | ``` 10 | go get github.com/xlcetc/cryptogm 11 | ``` 12 | 13 | # Benchmark 14 | 15 | CPU: intel core i7-7700 @3.6GHz. 16 | 17 | ## sm2 18 | 19 | ``` 20 | BenchmarkSign-8 19392 ns/op 21 | BenchmarkVerify-8 30326 ns/op 22 | BenchmarkSignWithDigest-8 16701 ns/op 23 | BenchmarkVerifyWithDigest-8 26742 ns/op 24 | BenchmarkSignWithASN1-8 21251 ns/op 25 | BenchmarkVerifyWithASN1-8 30390 ns/op 26 | ``` 27 | 28 | ## sm3 29 | 30 | ``` 31 | BenchmarkHash8Bytes-8 220 ns/op 36.44 MB/s 32 | BenchmarkHash1K-8 2815 ns/op 363.71 MB/s 33 | BenchmarkHash8K-8 20422 ns/op 401.13 MB/s 34 | ``` 35 | 36 | ## sm4 37 | 38 | ``` 39 | BenchmarkSm4Ecb8Bytes-8 623 ns/op 12.83 MB/s 40 | BenchmarkSm4Ecb1K-8 10526 ns/op 97.29 MB/s 41 | BenchmarkSm4Ecb8K-8 80692 ns/op 101.52 MB/s 42 | BenchmarkSm4Cbc8Bytes-8 664 ns/op 12.05 MB/s 43 | BenchmarkSm4Cbc1K-8 12299 ns/op 83.26 MB/s 44 | BenchmarkSm4Cbc8K-8 95395 ns/op 85.87 MB/s 45 | ``` 46 | 47 | ## sm9 48 | 49 | ``` 50 | BenchmarkSign-8 543 2187579 ns/op 51 | BenchmarkVerify-8 338 3599817 ns/op 52 | ``` -------------------------------------------------------------------------------- /elliptic/sm9curve/README.md: -------------------------------------------------------------------------------- 1 | bn256 2 | ----- 3 | 4 | Package bn256 implements a particular bilinear group. 5 | 6 | Bilinear groups are the basis of many of the new cryptographic protocols that 7 | have been proposed over the past decade. They consist of a triplet of groups 8 | (G₁, G₂ and GT) such that there exists a function e(g₁ˣ,g₂ʸ)=gTˣʸ (where gₓ is a 9 | generator of the respective group). That function is called a pairing function. 10 | 11 | This package specifically implements the Optimal Ate pairing over a 256-bit 12 | Barreto-Naehrig curve as described in 13 | http://cryptojedi.org/papers/dclxvi-20100714.pdf. Its output is compatible with 14 | the implementation described in that paper. 15 | 16 | This package previously claimed to operate at a 128-bit security level. However, 17 | recent improvements in attacks mean that is no longer true. See 18 | https://moderncrypto.org/mail-archive/curves/2016/000740.html. 19 | 20 | ### Benchmarks 21 | 22 | branch `master`: 23 | ``` 24 | BenchmarkG1-4 10000 154995 ns/op 25 | BenchmarkG2-4 3000 541503 ns/op 26 | BenchmarkGT-4 1000 1267811 ns/op 27 | BenchmarkPairing-4 1000 1630584 ns/op 28 | ``` 29 | 30 | branch `lattices`: 31 | ``` 32 | BenchmarkG1-4 20000 92198 ns/op 33 | BenchmarkG2-4 5000 340622 ns/op 34 | BenchmarkGT-4 2000 635061 ns/op 35 | BenchmarkPairing-4 1000 1629943 ns/op 36 | ``` 37 | 38 | official version: 39 | ``` 40 | BenchmarkG1-4 1000 2268491 ns/op 41 | BenchmarkG2-4 300 7227637 ns/op 42 | BenchmarkGT-4 100 15121359 ns/op 43 | BenchmarkPairing-4 50 20296164 ns/op 44 | ``` 45 | -------------------------------------------------------------------------------- /sm/sm9/sm9_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 cetc-30. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package sm9 6 | 7 | import ( 8 | "crypto/rand" 9 | "testing" 10 | ) 11 | 12 | func TestSign(t *testing.T) { 13 | mk, err := MasterKeyGen(rand.Reader) 14 | if err != nil { 15 | t.Errorf("mk gen failed:%s", err) 16 | return 17 | } 18 | 19 | var hid byte = 1 20 | 21 | var uid = []byte("Alice") 22 | 23 | uk, err := UserKeyGen(mk, uid, hid) 24 | if err != nil { 25 | t.Errorf("uk gen failed:%s", err) 26 | return 27 | } 28 | 29 | msg := []byte("message") 30 | 31 | sig, err := Sign(uk, &mk.MasterPubKey, msg) 32 | if err != nil { 33 | t.Errorf("sm9 sign failed:%s", err) 34 | return 35 | } 36 | 37 | if !Verify(sig, msg, uid, hid, &mk.MasterPubKey) { 38 | t.Error("sm9 sig is invalid") 39 | return 40 | } 41 | } 42 | 43 | func BenchmarkMasterKeyGen(b *testing.B) { 44 | for i := 0; i < b.N; i++ { 45 | _, _ = MasterKeyGen(rand.Reader) 46 | } 47 | } 48 | 49 | func BenchmarkUserKeyGen(b *testing.B) { 50 | mk, _ := MasterKeyGen(rand.Reader) 51 | id := []byte("Alice") 52 | hid := 3 53 | b.ResetTimer() 54 | for i := 0; i < b.N; i++ { 55 | _, _ = UserKeyGen(mk, id, byte(hid)) 56 | } 57 | } 58 | 59 | func BenchmarkSign(b *testing.B) { 60 | mk, _ := MasterKeyGen(rand.Reader) 61 | id := []byte("Alice") 62 | hid := 3 63 | uk, _ := UserKeyGen(mk, id, byte(hid)) 64 | 65 | var msg = []byte("message") 66 | 67 | b.ResetTimer() 68 | for i := 0; i < b.N; i++ { 69 | _, _ = Sign(uk, &mk.MasterPubKey, msg) 70 | } 71 | } 72 | 73 | func BenchmarkVerify(b *testing.B) { 74 | mk, _ := MasterKeyGen(rand.Reader) 75 | id := []byte("Alice") 76 | hid := 3 77 | uk, _ := UserKeyGen(mk, id, byte(hid)) 78 | 79 | var msg = []byte("message") 80 | 81 | sig, _ := Sign(uk, &mk.MasterPubKey, msg) 82 | 83 | b.ResetTimer() 84 | for i := 0; i < b.N; i++ { 85 | _ = Verify(sig, msg, id, byte(hid), &mk.MasterPubKey) 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /sm/sm3/sm3_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package sm3 6 | 7 | import ( 8 | "fmt" 9 | "testing" 10 | ) 11 | 12 | type sm3Test struct { 13 | out string 14 | in string 15 | } 16 | 17 | var testTable = []sm3Test{ 18 | {"1ab21d8355cfa17f8e61194831e81a8f22bec8c728fefb747ed035eb5082aa2b", ""}, 19 | {"623476ac18f65a2909e43c7fec61b49c7e764a91a18ccb82f1917a29c86c5e88", "a"}, 20 | {"e07d8ee6e54586a459e30eb8d809e02194558e2b0b235a31f3226a3687faab88", "ab"}, 21 | {"66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0", "abc"}, 22 | {"44f0061e69fa6fdfc290c494654a05dc0c053da7e5c52b84ef93a9d67d3fff88", "hello world"}, 23 | {"7c4b960e0fe034f670a8937636474b19b35724883b58da4dac37bb0675ec4d84", "sm3 test"}, 24 | {"3c28cfd2e1861b8e479013a7d078fe8ef4f14fd1f8b549ca53d58fffdedd912c", "sm3 hash"}, 25 | {"7a9a924ff292e09e72cd815b606357a796ac4351fe6de2ff59cd2967eb9a5c16", "sm3sm3sm3sm3sm3sm3sm3sm3sm3sm3sm3sm3"}, 26 | } 27 | 28 | func TestSM3(t *testing.T) { 29 | for i := 0; i < len(testTable); i++ { 30 | table := testTable[i] 31 | s := fmt.Sprintf("%x", SumSM3([]byte(table.in))) 32 | if s != table.out { 33 | t.Fatalf("SumSM3 function: SM3(%s) = %s want %s", table.in, s, table.out) 34 | } 35 | } 36 | } 37 | 38 | func TestSize(t *testing.T) { 39 | c := New() 40 | if got := c.Size(); got != Size { 41 | t.Errorf("Size = %d; want %d", got, Size) 42 | } 43 | } 44 | 45 | func TestBlockSize(t *testing.T) { 46 | c := New() 47 | if got := c.BlockSize(); got != BlockSize { 48 | t.Errorf("BlockSize = %d want %d", got, BlockSize) 49 | } 50 | } 51 | 52 | var bench = New() 53 | var buf = make([]byte, 8192) 54 | 55 | func benchmarkSize(b *testing.B, size int) { 56 | b.SetBytes(int64(size)) 57 | sum := make([]byte, bench.Size()) 58 | for i := 0; i < b.N; i++ { 59 | bench.Reset() 60 | bench.Write(buf[:size]) 61 | bench.Sum(sum[:0]) 62 | } 63 | } 64 | 65 | func BenchmarkHash8Bytes(b *testing.B) { 66 | benchmarkSize(b, 8) 67 | } 68 | 69 | func BenchmarkHash1K(b *testing.B) { 70 | benchmarkSize(b, 1024) 71 | } 72 | 73 | func BenchmarkHash8K(b *testing.B) { 74 | benchmarkSize(b, 8192) 75 | } 76 | -------------------------------------------------------------------------------- /elliptic/sm9curve/hash.go: -------------------------------------------------------------------------------- 1 | package sm9curve 2 | 3 | // HashG1 implements a hashing function into the G1 group. 4 | // 5 | // dst represents domain separation tag, similar to salt, for the hash. 6 | func HashG1(msg, dst []byte) *G1 { 7 | return mapToCurve(hashToBase(msg, dst)) 8 | } 9 | 10 | func mapToCurve(t *gfP) *G1 { 11 | one := *newGFp(1) 12 | 13 | // calculate w = (s * t)/(1 + B + t^2) 14 | // we calculate w0 = s * t * (1 + B + t^2) and inverse of it, so that w = (st)^2/w0 15 | // and then later x3 = 1 + (1 + B + t^2)^4/w0^2 16 | w := &gfP{} 17 | 18 | // a = (1 + B + t^2) 19 | a := &gfP{} 20 | t2 := &gfP{} 21 | gfpMul(t2, t, t) 22 | gfpAdd(a, curveB, t2) 23 | gfpAdd(a, a, &one) 24 | 25 | st := &gfP{} 26 | gfpMul(st, s, t) 27 | 28 | w0 := &gfP{} 29 | gfpMul(w0, st, a) 30 | w0.Invert(w0) 31 | 32 | gfpMul(w, st, st) 33 | gfpMul(w, w, w0) 34 | 35 | e := sign0(t) 36 | cp := &curvePoint{z: one, t: one} 37 | 38 | // calculate x1 = ((-1 + s) / 2) - t * w 39 | tw := &gfP{} 40 | gfpMul(tw, t, w) 41 | x1 := &gfP{} 42 | gfpSub(x1, sMinus1Over2, tw) 43 | 44 | // check if y=x1^3+5 is a square 45 | y := &gfP{} 46 | y.Set(x1) 47 | gfpMul(y, x1, x1) 48 | gfpMul(y, y, x1) 49 | gfpAdd(y, y, curveB) 50 | if legendre(y) == 1 { 51 | cp.x = *x1 52 | y.Sqrt(y) 53 | if e != sign0(y) { 54 | gfpNeg(y, y) 55 | } 56 | cp.y = *y 57 | return &G1{cp} 58 | } 59 | 60 | // calculate x2 = -1 - x1 61 | x2 := newGFp(-1) 62 | gfpSub(x2, x2, x1) 63 | 64 | // check if y=x2^3+5 is a square 65 | y.Set(x2) 66 | gfpMul(y, x2, x2) 67 | gfpMul(y, y, x2) 68 | gfpAdd(y, y, curveB) 69 | if legendre(y) == 1 { 70 | cp.x = *x2 71 | y.Sqrt(y) 72 | if e != sign0(y) { 73 | gfpNeg(y, y) 74 | } 75 | cp.y = *y 76 | return &G1{cp} 77 | } 78 | 79 | // calculate x3 = 1 + (1/ww) = 1 + a^4 * w0^2 80 | x3 := &gfP{} 81 | gfpMul(x3, a, a) 82 | gfpMul(x3, x3, x3) 83 | gfpMul(x3, x3, w0) 84 | gfpMul(x3, x3, w0) 85 | gfpAdd(x3, x3, &one) 86 | 87 | y.Set(x3) 88 | gfpMul(y, x3, x3) 89 | gfpMul(y, y, x3) 90 | gfpAdd(y, y, curveB) 91 | 92 | cp.x = *x3 93 | y.Sqrt(y) 94 | if e != sign0(y) { 95 | gfpNeg(y, y) 96 | } 97 | cp.y = *y 98 | 99 | return &G1{cp} 100 | } 101 | -------------------------------------------------------------------------------- /elliptic/sm9curve/gfp_arm64.s: -------------------------------------------------------------------------------- 1 | // +build !arm64,!generic 2 | 3 | #define storeBlock(a0,a1,a2,a3, r) \ 4 | MOVD a0, 0+r \ 5 | MOVD a1, 8+r \ 6 | MOVD a2, 16+r \ 7 | MOVD a3, 24+r 8 | 9 | #define loadBlock(r, a0,a1,a2,a3) \ 10 | MOVD 0+r, a0 \ 11 | MOVD 8+r, a1 \ 12 | MOVD 16+r, a2 \ 13 | MOVD 24+r, a3 14 | 15 | #define loadModulus(p0,p1,p2,p3) \ 16 | MOVD ·p2+0(SB), p0 \ 17 | MOVD ·p2+8(SB), p1 \ 18 | MOVD ·p2+16(SB), p2 \ 19 | MOVD ·p2+24(SB), p3 20 | 21 | #include "mul_arm64.h" 22 | 23 | TEXT ·gfpNeg(SB),0,$0-16 24 | MOVD a+8(FP), R0 25 | loadBlock(0(R0), R1,R2,R3,R4) 26 | loadModulus(R5,R6,R7,R8) 27 | 28 | SUBS R1, R5, R1 29 | SBCS R2, R6, R2 30 | SBCS R3, R7, R3 31 | SBCS R4, R8, R4 32 | 33 | SUBS R5, R1, R5 34 | SBCS R6, R2, R6 35 | SBCS R7, R3, R7 36 | SBCS R8, R4, R8 37 | 38 | CSEL CS, R5, R1, R1 39 | CSEL CS, R6, R2, R2 40 | CSEL CS, R7, R3, R3 41 | CSEL CS, R8, R4, R4 42 | 43 | MOVD c+0(FP), R0 44 | storeBlock(R1,R2,R3,R4, 0(R0)) 45 | RET 46 | 47 | TEXT ·gfpAdd(SB),0,$0-24 48 | MOVD a+8(FP), R0 49 | loadBlock(0(R0), R1,R2,R3,R4) 50 | MOVD b+16(FP), R0 51 | loadBlock(0(R0), R5,R6,R7,R8) 52 | loadModulus(R9,R10,R11,R12) 53 | MOVD ZR, R0 54 | 55 | ADDS R5, R1 56 | ADCS R6, R2 57 | ADCS R7, R3 58 | ADCS R8, R4 59 | ADCS ZR, R0 60 | 61 | SUBS R9, R1, R5 62 | SBCS R10, R2, R6 63 | SBCS R11, R3, R7 64 | SBCS R12, R4, R8 65 | SBCS ZR, R0, R0 66 | 67 | CSEL CS, R5, R1, R1 68 | CSEL CS, R6, R2, R2 69 | CSEL CS, R7, R3, R3 70 | CSEL CS, R8, R4, R4 71 | 72 | MOVD c+0(FP), R0 73 | storeBlock(R1,R2,R3,R4, 0(R0)) 74 | RET 75 | 76 | TEXT ·gfpSub(SB),0,$0-24 77 | MOVD a+8(FP), R0 78 | loadBlock(0(R0), R1,R2,R3,R4) 79 | MOVD b+16(FP), R0 80 | loadBlock(0(R0), R5,R6,R7,R8) 81 | loadModulus(R9,R10,R11,R12) 82 | 83 | SUBS R5, R1 84 | SBCS R6, R2 85 | SBCS R7, R3 86 | SBCS R8, R4 87 | 88 | CSEL CS, ZR, R9, R9 89 | CSEL CS, ZR, R10, R10 90 | CSEL CS, ZR, R11, R11 91 | CSEL CS, ZR, R12, R12 92 | 93 | ADDS R9, R1 94 | ADCS R10, R2 95 | ADCS R11, R3 96 | ADCS R12, R4 97 | 98 | MOVD c+0(FP), R0 99 | storeBlock(R1,R2,R3,R4, 0(R0)) 100 | RET 101 | 102 | TEXT ·gfpMul(SB),0,$0-24 103 | MOVD a+8(FP), R0 104 | loadBlock(0(R0), R1,R2,R3,R4) 105 | MOVD b+16(FP), R0 106 | loadBlock(0(R0), R5,R6,R7,R8) 107 | 108 | mul(R9,R10,R11,R12,R13,R14,R15,R16) 109 | gfpReduce() 110 | 111 | MOVD c+0(FP), R0 112 | storeBlock(R1,R2,R3,R4, 0(R0)) 113 | RET 114 | -------------------------------------------------------------------------------- /sm/sm2/external.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 cetc-30. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package sm2 6 | 7 | import ( 8 | "crypto/rand" 9 | "encoding/asn1" 10 | "github.com/xlcetc/cryptogm/elliptic/sm2curve" 11 | "io" 12 | "math/big" 13 | ) 14 | 15 | type Sm2PrivateKey struct { 16 | D *big.Int //sk 17 | } 18 | 19 | type Sm2PublicKey struct { 20 | X *big.Int //pk.X 21 | Y *big.Int //pk.Y 22 | } 23 | 24 | type sm2Signature struct { 25 | R, S *big.Int 26 | } 27 | 28 | func (priv *PrivateKey) Sign(rand io.Reader, msg []byte) ([]byte, error) { 29 | r, s, err := Sign(rand, priv, msg) 30 | if err != nil { 31 | return nil, err 32 | } 33 | return asn1.Marshal(sm2Signature{r, s}) 34 | } 35 | 36 | func (pub *PublicKey) Verify(msg []byte, sign []byte) bool { 37 | var sm2Sign sm2Signature 38 | _, err := asn1.Unmarshal(sign, &sm2Sign) 39 | if err != nil { 40 | return false 41 | } 42 | return Verify(pub, msg, sm2Sign.R, sm2Sign.S) 43 | } 44 | 45 | func Sm2KeyGen(rand io.Reader) (sk, pk []byte, err error) { 46 | priv, _ := GenerateKey(rand) 47 | var sm2SK Sm2PrivateKey 48 | var sm2PK Sm2PublicKey 49 | 50 | sm2SK.D = priv.D 51 | sm2PK.X = priv.X 52 | sm2PK.Y = priv.Y 53 | 54 | sk, _ = asn1.Marshal(sm2SK) 55 | pk, _ = asn1.Marshal(sm2PK) 56 | return 57 | } 58 | 59 | func Sm2Sign(sk, pk, msg []byte) ([]byte, error) { 60 | var sm2SK Sm2PrivateKey 61 | var sm2PK Sm2PublicKey 62 | _, err := asn1.Unmarshal(sk, &sm2SK) 63 | if err != nil { 64 | return nil, err 65 | } 66 | 67 | _, err = asn1.Unmarshal(pk, &sm2PK) 68 | if err != nil { 69 | return nil, err 70 | } 71 | 72 | var priv PrivateKey 73 | priv.Curve = sm2curve.P256() 74 | priv.D = sm2SK.D 75 | priv.X = sm2PK.X 76 | priv.Y = sm2PK.Y 77 | 78 | r, s, err := Sign(rand.Reader, &priv, msg) 79 | if err != nil { 80 | return nil, err 81 | } 82 | 83 | return asn1.Marshal(sm2Signature{r, s}) 84 | } 85 | 86 | func Sm2Verify(sign, pk, msg []byte) bool { 87 | var sm2Sign sm2Signature 88 | var sm2PK Sm2PublicKey 89 | 90 | _, err := asn1.Unmarshal(sign, &sm2Sign) 91 | if err != nil { 92 | return false 93 | } 94 | 95 | _, err = asn1.Unmarshal(pk, &sm2PK) 96 | if err != nil { 97 | return false 98 | } 99 | 100 | var PK PublicKey 101 | PK.Curve = sm2curve.P256() 102 | PK.X = sm2PK.X 103 | PK.Y = sm2PK.Y 104 | 105 | return PK.Verify(msg, sign) 106 | } 107 | -------------------------------------------------------------------------------- /elliptic/sm9curve/mul_bmi2_amd64.h: -------------------------------------------------------------------------------- 1 | #define mulBMI2(a0,a1,a2,a3, rb) \ 2 | MOVQ a0, DX \ 3 | MOVQ $0, R13 \ 4 | MULXQ 0+rb, R8, R9 \ 5 | MULXQ 8+rb, AX, R10 \ 6 | ADDQ AX, R9 \ 7 | MULXQ 16+rb, AX, R11 \ 8 | ADCQ AX, R10 \ 9 | MULXQ 24+rb, AX, R12 \ 10 | ADCQ AX, R11 \ 11 | ADCQ $0, R12 \ 12 | ADCQ $0, R13 \ 13 | \ 14 | MOVQ a1, DX \ 15 | MOVQ $0, R14 \ 16 | MULXQ 0+rb, AX, BX \ 17 | ADDQ AX, R9 \ 18 | ADCQ BX, R10 \ 19 | MULXQ 16+rb, AX, BX \ 20 | ADCQ AX, R11 \ 21 | ADCQ BX, R12 \ 22 | ADCQ $0, R13 \ 23 | MULXQ 8+rb, AX, BX \ 24 | ADDQ AX, R10 \ 25 | ADCQ BX, R11 \ 26 | MULXQ 24+rb, AX, BX \ 27 | ADCQ AX, R12 \ 28 | ADCQ BX, R13 \ 29 | ADCQ $0, R14 \ 30 | \ 31 | MOVQ a2, DX \ 32 | MOVQ $0, R15 \ 33 | MULXQ 0+rb, AX, BX \ 34 | ADDQ AX, R10 \ 35 | ADCQ BX, R11 \ 36 | MULXQ 16+rb, AX, BX \ 37 | ADCQ AX, R12 \ 38 | ADCQ BX, R13 \ 39 | ADCQ $0, R14 \ 40 | MULXQ 8+rb, AX, BX \ 41 | ADDQ AX, R11 \ 42 | ADCQ BX, R12 \ 43 | MULXQ 24+rb, AX, BX \ 44 | ADCQ AX, R13 \ 45 | ADCQ BX, R14 \ 46 | ADCQ $0, R15 \ 47 | \ 48 | MOVQ a3, DX \ 49 | MULXQ 0+rb, AX, BX \ 50 | ADDQ AX, R11 \ 51 | ADCQ BX, R12 \ 52 | MULXQ 16+rb, AX, BX \ 53 | ADCQ AX, R13 \ 54 | ADCQ BX, R14 \ 55 | ADCQ $0, R15 \ 56 | MULXQ 8+rb, AX, BX \ 57 | ADDQ AX, R12 \ 58 | ADCQ BX, R13 \ 59 | MULXQ 24+rb, AX, BX \ 60 | ADCQ AX, R14 \ 61 | ADCQ BX, R15 62 | 63 | #define gfpReduceBMI2() \ 64 | \ // m = (T * N') mod R, store m in R8:R9:R10:R11 65 | MOVQ ·np+0(SB), DX \ 66 | MULXQ 0(SP), R8, R9 \ 67 | MULXQ 8(SP), AX, R10 \ 68 | ADDQ AX, R9 \ 69 | MULXQ 16(SP), AX, R11 \ 70 | ADCQ AX, R10 \ 71 | MULXQ 24(SP), AX, BX \ 72 | ADCQ AX, R11 \ 73 | \ 74 | MOVQ ·np+8(SB), DX \ 75 | MULXQ 0(SP), AX, BX \ 76 | ADDQ AX, R9 \ 77 | ADCQ BX, R10 \ 78 | MULXQ 16(SP), AX, BX \ 79 | ADCQ AX, R11 \ 80 | MULXQ 8(SP), AX, BX \ 81 | ADDQ AX, R10 \ 82 | ADCQ BX, R11 \ 83 | \ 84 | MOVQ ·np+16(SB), DX \ 85 | MULXQ 0(SP), AX, BX \ 86 | ADDQ AX, R10 \ 87 | ADCQ BX, R11 \ 88 | MULXQ 8(SP), AX, BX \ 89 | ADDQ AX, R11 \ 90 | \ 91 | MOVQ ·np+24(SB), DX \ 92 | MULXQ 0(SP), AX, BX \ 93 | ADDQ AX, R11 \ 94 | \ 95 | storeBlock(R8,R9,R10,R11, 64(SP)) \ 96 | \ 97 | \ // m * N 98 | mulBMI2(·p2+0(SB),·p2+8(SB),·p2+16(SB),·p2+24(SB), 64(SP)) \ 99 | \ 100 | \ // Add the 512-bit intermediate to m*N 101 | MOVQ $0, AX \ 102 | ADDQ 0(SP), R8 \ 103 | ADCQ 8(SP), R9 \ 104 | ADCQ 16(SP), R10 \ 105 | ADCQ 24(SP), R11 \ 106 | ADCQ 32(SP), R12 \ 107 | ADCQ 40(SP), R13 \ 108 | ADCQ 48(SP), R14 \ 109 | ADCQ 56(SP), R15 \ 110 | ADCQ $0, AX \ 111 | \ 112 | gfpCarry(R12,R13,R14,R15,AX, R8,R9,R10,R11,BX) 113 | -------------------------------------------------------------------------------- /elliptic/sm9curve/gfp_amd64.s: -------------------------------------------------------------------------------- 1 | // +build amd64,!generic 2 | 3 | #define storeBlock(a0,a1,a2,a3, r) \ 4 | MOVQ a0, 0+r \ 5 | MOVQ a1, 8+r \ 6 | MOVQ a2, 16+r \ 7 | MOVQ a3, 24+r 8 | 9 | #define loadBlock(r, a0,a1,a2,a3) \ 10 | MOVQ 0+r, a0 \ 11 | MOVQ 8+r, a1 \ 12 | MOVQ 16+r, a2 \ 13 | MOVQ 24+r, a3 14 | 15 | #define gfpCarry(a0,a1,a2,a3,a4, b0,b1,b2,b3,b4) \ 16 | \ // b = a-p 17 | MOVQ a0, b0 \ 18 | MOVQ a1, b1 \ 19 | MOVQ a2, b2 \ 20 | MOVQ a3, b3 \ 21 | MOVQ a4, b4 \ 22 | \ 23 | SUBQ ·p2+0(SB), b0 \ 24 | SBBQ ·p2+8(SB), b1 \ 25 | SBBQ ·p2+16(SB), b2 \ 26 | SBBQ ·p2+24(SB), b3 \ 27 | SBBQ $0, b4 \ 28 | \ 29 | \ // if b is negative then return a 30 | \ // else return b 31 | CMOVQCC b0, a0 \ 32 | CMOVQCC b1, a1 \ 33 | CMOVQCC b2, a2 \ 34 | CMOVQCC b3, a3 35 | 36 | #include "mul_amd64.h" 37 | #include "mul_bmi2_amd64.h" 38 | 39 | TEXT ·gfpNeg(SB),0,$0-16 40 | MOVQ ·p2+0(SB), R8 41 | MOVQ ·p2+8(SB), R9 42 | MOVQ ·p2+16(SB), R10 43 | MOVQ ·p2+24(SB), R11 44 | 45 | MOVQ a+8(FP), DI 46 | SUBQ 0(DI), R8 47 | SBBQ 8(DI), R9 48 | SBBQ 16(DI), R10 49 | SBBQ 24(DI), R11 50 | 51 | MOVQ $0, AX 52 | gfpCarry(R8,R9,R10,R11,AX, R12,R13,R14,R15,BX) 53 | 54 | MOVQ c+0(FP), DI 55 | storeBlock(R8,R9,R10,R11, 0(DI)) 56 | RET 57 | 58 | TEXT ·gfpAdd(SB),0,$0-24 59 | MOVQ a+8(FP), DI 60 | MOVQ b+16(FP), SI 61 | 62 | loadBlock(0(DI), R8,R9,R10,R11) 63 | MOVQ $0, R12 64 | 65 | ADDQ 0(SI), R8 66 | ADCQ 8(SI), R9 67 | ADCQ 16(SI), R10 68 | ADCQ 24(SI), R11 69 | ADCQ $0, R12 70 | 71 | gfpCarry(R8,R9,R10,R11,R12, R13,R14,R15,AX,BX) 72 | 73 | MOVQ c+0(FP), DI 74 | storeBlock(R8,R9,R10,R11, 0(DI)) 75 | RET 76 | 77 | TEXT ·gfpSub(SB),0,$0-24 78 | MOVQ a+8(FP), DI 79 | MOVQ b+16(FP), SI 80 | 81 | loadBlock(0(DI), R8,R9,R10,R11) 82 | 83 | MOVQ ·p2+0(SB), R12 84 | MOVQ ·p2+8(SB), R13 85 | MOVQ ·p2+16(SB), R14 86 | MOVQ ·p2+24(SB), R15 87 | MOVQ $0, AX 88 | 89 | SUBQ 0(SI), R8 90 | SBBQ 8(SI), R9 91 | SBBQ 16(SI), R10 92 | SBBQ 24(SI), R11 93 | 94 | CMOVQCC AX, R12 95 | CMOVQCC AX, R13 96 | CMOVQCC AX, R14 97 | CMOVQCC AX, R15 98 | 99 | ADDQ R12, R8 100 | ADCQ R13, R9 101 | ADCQ R14, R10 102 | ADCQ R15, R11 103 | 104 | MOVQ c+0(FP), DI 105 | storeBlock(R8,R9,R10,R11, 0(DI)) 106 | RET 107 | 108 | TEXT ·gfpMul(SB),0,$160-24 109 | MOVQ a+8(FP), DI 110 | MOVQ b+16(FP), SI 111 | 112 | // Jump to a slightly different implementation if MULX isn't supported. 113 | CMPB ·hasBMI2(SB), $0 114 | JE nobmi2Mul 115 | 116 | mulBMI2(0(DI),8(DI),16(DI),24(DI), 0(SI)) 117 | storeBlock( R8, R9,R10,R11, 0(SP)) 118 | storeBlock(R12,R13,R14,R15, 32(SP)) 119 | gfpReduceBMI2() 120 | JMP end 121 | 122 | nobmi2Mul: 123 | mul(0(DI),8(DI),16(DI),24(DI), 0(SI), 0(SP)) 124 | gfpReduce(0(SP)) 125 | 126 | end: 127 | MOVQ c+0(FP), DI 128 | storeBlock(R12,R13,R14,R15, 0(DI)) 129 | RET 130 | -------------------------------------------------------------------------------- /elliptic/sm9curve/mul_arm64.h: -------------------------------------------------------------------------------- 1 | #define mul(c0,c1,c2,c3,c4,c5,c6,c7) \ 2 | MUL R1, R5, c0 \ 3 | UMULH R1, R5, c1 \ 4 | MUL R1, R6, R0 \ 5 | ADDS R0, c1 \ 6 | UMULH R1, R6, c2 \ 7 | MUL R1, R7, R0 \ 8 | ADCS R0, c2 \ 9 | UMULH R1, R7, c3 \ 10 | MUL R1, R8, R0 \ 11 | ADCS R0, c3 \ 12 | UMULH R1, R8, c4 \ 13 | ADCS ZR, c4 \ 14 | \ 15 | MUL R2, R5, R1 \ 16 | UMULH R2, R5, R26 \ 17 | MUL R2, R6, R0 \ 18 | ADDS R0, R26 \ 19 | UMULH R2, R6, R27 \ 20 | MUL R2, R7, R0 \ 21 | ADCS R0, R27 \ 22 | UMULH R2, R7, R29 \ 23 | MUL R2, R8, R0 \ 24 | ADCS R0, R29 \ 25 | UMULH R2, R8, c5 \ 26 | ADCS ZR, c5 \ 27 | ADDS R1, c1 \ 28 | ADCS R26, c2 \ 29 | ADCS R27, c3 \ 30 | ADCS R29, c4 \ 31 | ADCS ZR, c5 \ 32 | \ 33 | MUL R3, R5, R1 \ 34 | UMULH R3, R5, R26 \ 35 | MUL R3, R6, R0 \ 36 | ADDS R0, R26 \ 37 | UMULH R3, R6, R27 \ 38 | MUL R3, R7, R0 \ 39 | ADCS R0, R27 \ 40 | UMULH R3, R7, R29 \ 41 | MUL R3, R8, R0 \ 42 | ADCS R0, R29 \ 43 | UMULH R3, R8, c6 \ 44 | ADCS ZR, c6 \ 45 | ADDS R1, c2 \ 46 | ADCS R26, c3 \ 47 | ADCS R27, c4 \ 48 | ADCS R29, c5 \ 49 | ADCS ZR, c6 \ 50 | \ 51 | MUL R4, R5, R1 \ 52 | UMULH R4, R5, R26 \ 53 | MUL R4, R6, R0 \ 54 | ADDS R0, R26 \ 55 | UMULH R4, R6, R27 \ 56 | MUL R4, R7, R0 \ 57 | ADCS R0, R27 \ 58 | UMULH R4, R7, R29 \ 59 | MUL R4, R8, R0 \ 60 | ADCS R0, R29 \ 61 | UMULH R4, R8, c7 \ 62 | ADCS ZR, c7 \ 63 | ADDS R1, c3 \ 64 | ADCS R26, c4 \ 65 | ADCS R27, c5 \ 66 | ADCS R29, c6 \ 67 | ADCS ZR, c7 68 | 69 | #define gfpReduce() \ 70 | \ // m = (T * N') mod R, store m in R1:R2:R3:R4 71 | MOVD ·np+0(SB), R17 \ 72 | MOVD ·np+8(SB), R25 \ 73 | MOVD ·np+16(SB), R19 \ 74 | MOVD ·np+24(SB), R20 \ 75 | \ 76 | MUL R9, R17, R1 \ 77 | UMULH R9, R17, R2 \ 78 | MUL R9, R25, R0 \ 79 | ADDS R0, R2 \ 80 | UMULH R9, R25, R3 \ 81 | MUL R9, R19, R0 \ 82 | ADCS R0, R3 \ 83 | UMULH R9, R19, R4 \ 84 | MUL R9, R20, R0 \ 85 | ADCS R0, R4 \ 86 | \ 87 | MUL R10, R17, R21 \ 88 | UMULH R10, R17, R22 \ 89 | MUL R10, R25, R0 \ 90 | ADDS R0, R22 \ 91 | UMULH R10, R25, R23 \ 92 | MUL R10, R19, R0 \ 93 | ADCS R0, R23 \ 94 | ADDS R21, R2 \ 95 | ADCS R22, R3 \ 96 | ADCS R23, R4 \ 97 | \ 98 | MUL R11, R17, R21 \ 99 | UMULH R11, R17, R22 \ 100 | MUL R11, R25, R0 \ 101 | ADDS R0, R22 \ 102 | ADDS R21, R3 \ 103 | ADCS R22, R4 \ 104 | \ 105 | MUL R12, R17, R21 \ 106 | ADDS R21, R4 \ 107 | \ 108 | \ // m * N 109 | loadModulus(R5,R6,R7,R8) \ 110 | mul(R17,R25,R19,R20,R21,R22,R23,R24) \ 111 | \ 112 | \ // Add the 512-bit intermediate to m*N 113 | MOVD ZR, R0 \ 114 | ADDS R9, R17 \ 115 | ADCS R10, R25 \ 116 | ADCS R11, R19 \ 117 | ADCS R12, R20 \ 118 | ADCS R13, R21 \ 119 | ADCS R14, R22 \ 120 | ADCS R15, R23 \ 121 | ADCS R16, R24 \ 122 | ADCS ZR, R0 \ 123 | \ 124 | \ // Our output is R21:R22:R23:R24. Reduce mod p if necessary. 125 | SUBS R5, R21, R10 \ 126 | SBCS R6, R22, R11 \ 127 | SBCS R7, R23, R12 \ 128 | SBCS R8, R24, R13 \ 129 | \ 130 | CSEL CS, R10, R21, R1 \ 131 | CSEL CS, R11, R22, R2 \ 132 | CSEL CS, R12, R23, R3 \ 133 | CSEL CS, R13, R24, R4 134 | -------------------------------------------------------------------------------- /sm/sm3/sm3.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package sm3 6 | 7 | import ( 8 | "hash" 9 | ) 10 | 11 | // The size of a SM3 checksum in bytes. 12 | const Size = 32 13 | 14 | // The blocksize of SM3 in bytes. 15 | const BlockSize = 64 16 | 17 | const ( 18 | chunk = 64 19 | init0 = 0x7380166f 20 | init1 = 0x4914b2b9 21 | init2 = 0x172442d7 22 | init3 = 0xda8a0600 23 | init4 = 0xa96f30bc 24 | init5 = 0x163138aa 25 | init6 = 0xe38dee4d 26 | init7 = 0xb0fb0e4e 27 | ) 28 | 29 | // digest represents the partial evaluation of a checksum. 30 | type digest struct { 31 | h [8]uint32 32 | x [chunk]byte 33 | nx int 34 | len uint64 35 | } 36 | 37 | func (d *digest) Reset() { 38 | d.h[0] = init0 39 | d.h[1] = init1 40 | d.h[2] = init2 41 | d.h[3] = init3 42 | d.h[4] = init4 43 | d.h[5] = init5 44 | d.h[6] = init6 45 | d.h[7] = init7 46 | d.nx = 0 47 | d.len = 0 48 | } 49 | 50 | func New() hash.Hash { 51 | d := new(digest) 52 | d.Reset() 53 | return d 54 | } 55 | 56 | func (d *digest) Size() int { 57 | return Size 58 | } 59 | 60 | func (d *digest) BlockSize() int { return BlockSize } 61 | 62 | func (d *digest) Write(p []byte) (nn int, err error) { 63 | nn = len(p) 64 | d.len += uint64(nn) 65 | //var n int 66 | if d.nx > 0 { 67 | n := copy(d.x[d.nx:], p) 68 | d.nx += n 69 | if d.nx == chunk { 70 | //if cpu.X86.HasAVX2 && cpu.X86.HasBMI2 { 71 | // block(d, d.x[:]) 72 | //} else { 73 | // Block(d, d.x[:]) 74 | //} 75 | block(d, d.x[:]) 76 | d.nx = 0 77 | } 78 | p = p[n:] 79 | } 80 | 81 | if len(p) >= chunk { 82 | n := len(p) &^ (chunk - 1) 83 | //if cpu.X86.HasAVX2 && cpu.X86.HasBMI2 { 84 | // block(d, p[:n]) 85 | //} else { 86 | // Block(d, p[:n]) 87 | //} 88 | block(d, p[:n]) 89 | p = p[n:] 90 | } 91 | if len(p) > 0 { 92 | d.nx = copy(d.x[:], p) 93 | } 94 | return 95 | } 96 | 97 | func (d0 *digest) Sum(in []byte) []byte { 98 | // Make a copy of d0 so that caller can keep writing and summing. 99 | d := *d0 100 | hash := d.checkSum() 101 | return append(in, hash[:]...) 102 | } 103 | 104 | func (d *digest) checkSum() [Size]byte { 105 | len := d.len 106 | // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. 107 | var tmp [64]byte 108 | tmp[0] = 0x80 109 | if len%64 < 56 { 110 | d.Write(tmp[0 : 56-len%64]) 111 | } else { 112 | d.Write(tmp[0 : 64+56-len%64]) 113 | } 114 | 115 | // Length in bits. 116 | len <<= 3 117 | for i := uint(0); i < 8; i++ { 118 | tmp[i] = byte(len >> (56 - 8*i)) 119 | } 120 | d.Write(tmp[0:8]) 121 | 122 | if d.nx != 0 { 123 | panic("d.nx != 0") 124 | } 125 | 126 | h := d.h[:] 127 | 128 | var digest [Size]byte 129 | for i, s := range h { 130 | digest[i*4] = byte(s >> 24) 131 | digest[i*4+1] = byte(s >> 16) 132 | digest[i*4+2] = byte(s >> 8) 133 | digest[i*4+3] = byte(s) 134 | } 135 | return digest 136 | 137 | } 138 | 139 | func SumSM3(data []byte) [Size]byte { 140 | var d digest 141 | d.Reset() 142 | d.Write(data) 143 | return d.checkSum() 144 | } 145 | -------------------------------------------------------------------------------- /elliptic/sm9curve/genpara/genconsts/gfp2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/big" 6 | ) 7 | 8 | type gfP2 struct { 9 | p *big.Int 10 | x, y *big.Int 11 | } 12 | 13 | func newGFp2(p *big.Int) *gfP2 { 14 | return &gfP2{ 15 | p: new(big.Int).Set(p), 16 | x: new(big.Int), 17 | y: new(big.Int), 18 | } 19 | } 20 | 21 | //cloudflare bn256: i²=-1 22 | func (c *gfP2) Mul(a, b *gfP2) *gfP2 { 23 | t1, t2 := new(big.Int), new(big.Int) 24 | t1.Mul(a.y, b.y) 25 | t2.Mul(a.x, b.x) 26 | t1.Sub(t1, t2).Mod(t1, c.p) 27 | 28 | t3 := new(big.Int) 29 | t2.Mul(a.x, b.y) 30 | t3.Mul(a.y, b.x) 31 | 32 | c.x.Add(t2, t3).Mod(c.x, c.p) 33 | c.y.Set(t1) 34 | return c 35 | } 36 | 37 | func (c *gfP2) Exp(a *gfP2, scalar *big.Int) *gfP2 { 38 | sum, t := newGFp2(c.p), newGFp2(c.p) 39 | sum.y.SetInt64(1) 40 | 41 | for i := scalar.BitLen(); i >= 0; i-- { 42 | t.Mul(sum, sum) 43 | if scalar.Bit(i) != 0 { 44 | sum.Mul(t, a) 45 | } else { 46 | sum.Set(t) 47 | } 48 | } 49 | 50 | c.Set(sum) 51 | return c 52 | } 53 | 54 | func (c *gfP2) MontEncode(bitSize uint) *gfP2 { 55 | c.x.Lsh(c.x, bitSize).Mod(c.x, c.p) 56 | c.y.Lsh(c.y, bitSize).Mod(c.y, c.p) 57 | 58 | return c 59 | } 60 | 61 | //sm9 bn256: i²=-2 62 | func (c *gfP2) Sm9Mul(a, b *gfP2) *gfP2 { 63 | t1, t2 := new(big.Int), new(big.Int) 64 | t1.Mul(a.y, b.y) 65 | t2.Mul(a.x, b.x) 66 | t1.Sub(t1, t2).Sub(t1, t2).Mod(t1, c.p) 67 | 68 | t3 := new(big.Int) 69 | t2.Mul(a.x, b.y) 70 | t3.Mul(a.y, b.x) 71 | 72 | c.x.Add(t2, t3).Mod(c.x, c.p) 73 | c.y.Set(t1) 74 | return c 75 | } 76 | 77 | func (c *gfP2) Sm9Exp(a *gfP2, scalar *big.Int) *gfP2 { 78 | sum, t := newGFp2(c.p), newGFp2(c.p) 79 | sum.y.SetInt64(1) 80 | 81 | for i := scalar.BitLen(); i >= 0; i-- { 82 | t.Sm9Mul(sum, sum) 83 | if scalar.Bit(i) != 0 { 84 | sum.Sm9Mul(t, a) 85 | } else { 86 | sum.Set(t) 87 | } 88 | } 89 | 90 | c.Set(sum) 91 | return c 92 | } 93 | 94 | func (c *gfP2) Set(a *gfP2) *gfP2 { 95 | c.x.Set(a.x) 96 | c.y.Set(a.y) 97 | return c 98 | } 99 | 100 | var zeroWordSlice = []big.Word{0, 0, 0, 0, 0, 0, 0, 0} 101 | 102 | func padding(w []big.Word) []big.Word { 103 | if len(w) <= 8 { 104 | w = append(zeroWordSlice[8-len(w):], w...) 105 | } 106 | 107 | return w 108 | } 109 | 110 | func (c *gfP2) Println() { 111 | fmt.Print("&gfP2{gfP{") 112 | words := c.x.Bits() 113 | for _, word := range words[:len(words)-1] { 114 | fmt.Printf("%#x, ", word) 115 | } 116 | fmt.Printf("%#x}, gfP{", words[len(words)-1]) 117 | words = c.y.Bits() 118 | for _, word := range words[:len(words)-1] { 119 | fmt.Printf("%#x, ", word) 120 | } 121 | fmt.Printf("%#x}}\n\n", words[len(words)-1]) 122 | } 123 | 124 | func (c *gfP2) PrintY() { 125 | fmt.Print("&gfP{") 126 | words := c.y.Bits() 127 | for _, word := range words[:len(words)-1] { 128 | fmt.Printf("%#x, ", word) 129 | } 130 | fmt.Printf("%#x}\n\n", words[len(words)-1]) 131 | } 132 | 133 | func (c *gfP2) PrintX() { 134 | fmt.Print("&gfP{") 135 | words := c.x.Bits() 136 | for _, word := range words[:len(words)-1] { 137 | fmt.Printf("%#x, ", word) 138 | } 139 | fmt.Printf("%#x}\n\n", words[len(words)-1]) 140 | } 141 | -------------------------------------------------------------------------------- /sm/sm4/sm4_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 cetc-30. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | package sm4 5 | 6 | import ( 7 | "bytes" 8 | "testing" 9 | ) 10 | 11 | func TestSm4Ecb(t *testing.T) { 12 | key := []byte("0123456789abcdef") 13 | msg := []byte("0123456789abcdef012345678") 14 | encMsg, err := Sm4Ecb(key, msg, ENC) 15 | if err != nil { 16 | t.Errorf("sm4 enc error:%s", err) 17 | return 18 | } 19 | dec, err := Sm4Ecb(key, encMsg, DEC) 20 | if err != nil { 21 | t.Errorf("sm4 dec error:%s", err) 22 | return 23 | } 24 | if !bytes.Equal(msg, dec) { 25 | t.Errorf("sm4 self enc and dec failed") 26 | } 27 | } 28 | 29 | var buf = make([]byte, 8192) 30 | 31 | func benchmarkSizeEcb(b *testing.B, size int) { 32 | b.SetBytes(int64(size)) 33 | key := []byte("1234567890abcdef") 34 | for i := 0; i < b.N; i++ { 35 | Sm4Ecb(key, buf[:size], ENC) 36 | } 37 | } 38 | 39 | func BenchmarkSm4Ecb8Bytes(b *testing.B) { 40 | benchmarkSizeEcb(b, 8) 41 | } 42 | 43 | func BenchmarkSm4Ecb1K(b *testing.B) { 44 | benchmarkSizeEcb(b, 1024) 45 | } 46 | 47 | func BenchmarkSm4Ecb8K(b *testing.B) { 48 | benchmarkSizeEcb(b, 8192) 49 | } 50 | 51 | func TestSm4CipherEncAndDec(t *testing.T) { 52 | msg := []byte("0123456789abcdef") 53 | key := []byte("0123456789abcdef") 54 | c, err := NewCipher(key) 55 | if err != nil { 56 | t.Errorf("cipher error:%s", err) 57 | return 58 | } 59 | 60 | encMsg := make([]byte, 16) 61 | c.Encrypt(encMsg, msg) 62 | 63 | plain := make([]byte, 16) 64 | c.Decrypt(plain, encMsg) 65 | 66 | if !bytes.Equal(msg, plain) { 67 | t.Error("sm4 self enc and dec failed") 68 | } 69 | } 70 | 71 | func BenchmarkSm4Cipher_Encrypt(b *testing.B) { 72 | msg := []byte("0123456789abcdef") 73 | key := []byte("0123456789abcdef") 74 | c, _ := NewCipher(key) 75 | encMsg := make([]byte, 16) 76 | 77 | b.SetBytes(int64(len(msg))) 78 | b.ResetTimer() 79 | for i := 0; i < b.N; i++ { 80 | c.Encrypt(encMsg, msg) 81 | } 82 | } 83 | 84 | func BenchmarkSm4Cipher_Decrypt(b *testing.B) { 85 | msg := []byte("0123456789abcdef") 86 | key := []byte("0123456789abcdef") 87 | c, _ := NewCipher(key) 88 | encMsg := make([]byte, 16) 89 | plain := make([]byte, 16) 90 | c.Encrypt(encMsg, msg) 91 | 92 | b.SetBytes(int64(len(msg))) 93 | b.ResetTimer() 94 | for i := 0; i < b.N; i++ { 95 | c.Decrypt(plain, encMsg) 96 | } 97 | } 98 | 99 | func TestSm4Cbc(t *testing.T) { 100 | msg := []byte("0123456789abcdef012345678") 101 | key := []byte("0123456789abcdef") 102 | 103 | c, err := Sm4Cbc(key, msg, ENC) 104 | if err != nil { 105 | t.Errorf("sm4 cbc enc err:%s", err) 106 | return 107 | } 108 | 109 | plain, err := Sm4Cbc(key, c, DEC) 110 | if err != nil { 111 | t.Errorf("sm4 cbc dec err:%s", err) 112 | return 113 | } 114 | 115 | if !bytes.Equal(msg, plain) { 116 | t.Error("sm4 encryption is invalid") 117 | return 118 | } 119 | } 120 | 121 | func benchmarkSizeCbc(b *testing.B, size int) { 122 | b.SetBytes(int64(size)) 123 | key := []byte("1234567890abcdef") 124 | for i := 0; i < b.N; i++ { 125 | Sm4Cbc(key, buf[:size], ENC) 126 | } 127 | } 128 | 129 | func BenchmarkSm4Cbc8Bytes(b *testing.B) { 130 | benchmarkSizeCbc(b, 8) 131 | } 132 | 133 | func BenchmarkSm4Cbc1K(b *testing.B) { 134 | benchmarkSizeCbc(b, 1024) 135 | } 136 | 137 | func BenchmarkSm4Cbc8K(b *testing.B) { 138 | benchmarkSizeCbc(b, 8192) 139 | } 140 | -------------------------------------------------------------------------------- /elliptic/sm9curve/mul_amd64.h: -------------------------------------------------------------------------------- 1 | #define mul(a0,a1,a2,a3, rb, stack) \ 2 | MOVQ a0, AX \ 3 | MULQ 0+rb \ 4 | MOVQ AX, R8 \ 5 | MOVQ DX, R9 \ 6 | MOVQ a0, AX \ 7 | MULQ 8+rb \ 8 | ADDQ AX, R9 \ 9 | ADCQ $0, DX \ 10 | MOVQ DX, R10 \ 11 | MOVQ a0, AX \ 12 | MULQ 16+rb \ 13 | ADDQ AX, R10 \ 14 | ADCQ $0, DX \ 15 | MOVQ DX, R11 \ 16 | MOVQ a0, AX \ 17 | MULQ 24+rb \ 18 | ADDQ AX, R11 \ 19 | ADCQ $0, DX \ 20 | MOVQ DX, R12 \ 21 | \ 22 | storeBlock(R8,R9,R10,R11, 0+stack) \ 23 | MOVQ R12, 32+stack \ 24 | \ 25 | MOVQ a1, AX \ 26 | MULQ 0+rb \ 27 | MOVQ AX, R8 \ 28 | MOVQ DX, R9 \ 29 | MOVQ a1, AX \ 30 | MULQ 8+rb \ 31 | ADDQ AX, R9 \ 32 | ADCQ $0, DX \ 33 | MOVQ DX, R10 \ 34 | MOVQ a1, AX \ 35 | MULQ 16+rb \ 36 | ADDQ AX, R10 \ 37 | ADCQ $0, DX \ 38 | MOVQ DX, R11 \ 39 | MOVQ a1, AX \ 40 | MULQ 24+rb \ 41 | ADDQ AX, R11 \ 42 | ADCQ $0, DX \ 43 | MOVQ DX, R12 \ 44 | \ 45 | ADDQ 8+stack, R8 \ 46 | ADCQ 16+stack, R9 \ 47 | ADCQ 24+stack, R10 \ 48 | ADCQ 32+stack, R11 \ 49 | ADCQ $0, R12 \ 50 | storeBlock(R8,R9,R10,R11, 8+stack) \ 51 | MOVQ R12, 40+stack \ 52 | \ 53 | MOVQ a2, AX \ 54 | MULQ 0+rb \ 55 | MOVQ AX, R8 \ 56 | MOVQ DX, R9 \ 57 | MOVQ a2, AX \ 58 | MULQ 8+rb \ 59 | ADDQ AX, R9 \ 60 | ADCQ $0, DX \ 61 | MOVQ DX, R10 \ 62 | MOVQ a2, AX \ 63 | MULQ 16+rb \ 64 | ADDQ AX, R10 \ 65 | ADCQ $0, DX \ 66 | MOVQ DX, R11 \ 67 | MOVQ a2, AX \ 68 | MULQ 24+rb \ 69 | ADDQ AX, R11 \ 70 | ADCQ $0, DX \ 71 | MOVQ DX, R12 \ 72 | \ 73 | ADDQ 16+stack, R8 \ 74 | ADCQ 24+stack, R9 \ 75 | ADCQ 32+stack, R10 \ 76 | ADCQ 40+stack, R11 \ 77 | ADCQ $0, R12 \ 78 | storeBlock(R8,R9,R10,R11, 16+stack) \ 79 | MOVQ R12, 48+stack \ 80 | \ 81 | MOVQ a3, AX \ 82 | MULQ 0+rb \ 83 | MOVQ AX, R8 \ 84 | MOVQ DX, R9 \ 85 | MOVQ a3, AX \ 86 | MULQ 8+rb \ 87 | ADDQ AX, R9 \ 88 | ADCQ $0, DX \ 89 | MOVQ DX, R10 \ 90 | MOVQ a3, AX \ 91 | MULQ 16+rb \ 92 | ADDQ AX, R10 \ 93 | ADCQ $0, DX \ 94 | MOVQ DX, R11 \ 95 | MOVQ a3, AX \ 96 | MULQ 24+rb \ 97 | ADDQ AX, R11 \ 98 | ADCQ $0, DX \ 99 | MOVQ DX, R12 \ 100 | \ 101 | ADDQ 24+stack, R8 \ 102 | ADCQ 32+stack, R9 \ 103 | ADCQ 40+stack, R10 \ 104 | ADCQ 48+stack, R11 \ 105 | ADCQ $0, R12 \ 106 | storeBlock(R8,R9,R10,R11, 24+stack) \ 107 | MOVQ R12, 56+stack 108 | 109 | #define gfpReduce(stack) \ 110 | \ // m = (T * N') mod R, store m in R8:R9:R10:R11 111 | MOVQ ·np+0(SB), AX \ 112 | MULQ 0+stack \ 113 | MOVQ AX, R8 \ 114 | MOVQ DX, R9 \ 115 | MOVQ ·np+0(SB), AX \ 116 | MULQ 8+stack \ 117 | ADDQ AX, R9 \ 118 | ADCQ $0, DX \ 119 | MOVQ DX, R10 \ 120 | MOVQ ·np+0(SB), AX \ 121 | MULQ 16+stack \ 122 | ADDQ AX, R10 \ 123 | ADCQ $0, DX \ 124 | MOVQ DX, R11 \ 125 | MOVQ ·np+0(SB), AX \ 126 | MULQ 24+stack \ 127 | ADDQ AX, R11 \ 128 | \ 129 | MOVQ ·np+8(SB), AX \ 130 | MULQ 0+stack \ 131 | MOVQ AX, R12 \ 132 | MOVQ DX, R13 \ 133 | MOVQ ·np+8(SB), AX \ 134 | MULQ 8+stack \ 135 | ADDQ AX, R13 \ 136 | ADCQ $0, DX \ 137 | MOVQ DX, R14 \ 138 | MOVQ ·np+8(SB), AX \ 139 | MULQ 16+stack \ 140 | ADDQ AX, R14 \ 141 | \ 142 | ADDQ R12, R9 \ 143 | ADCQ R13, R10 \ 144 | ADCQ R14, R11 \ 145 | \ 146 | MOVQ ·np+16(SB), AX \ 147 | MULQ 0+stack \ 148 | MOVQ AX, R12 \ 149 | MOVQ DX, R13 \ 150 | MOVQ ·np+16(SB), AX \ 151 | MULQ 8+stack \ 152 | ADDQ AX, R13 \ 153 | \ 154 | ADDQ R12, R10 \ 155 | ADCQ R13, R11 \ 156 | \ 157 | MOVQ ·np+24(SB), AX \ 158 | MULQ 0+stack \ 159 | ADDQ AX, R11 \ 160 | \ 161 | storeBlock(R8,R9,R10,R11, 64+stack) \ 162 | \ 163 | \ // m * N 164 | mul(·p2+0(SB),·p2+8(SB),·p2+16(SB),·p2+24(SB), 64+stack, 96+stack) \ 165 | \ 166 | \ // Add the 512-bit intermediate to m*N 167 | loadBlock(96+stack, R8,R9,R10,R11) \ 168 | loadBlock(128+stack, R12,R13,R14,R15) \ 169 | \ 170 | MOVQ $0, AX \ 171 | ADDQ 0+stack, R8 \ 172 | ADCQ 8+stack, R9 \ 173 | ADCQ 16+stack, R10 \ 174 | ADCQ 24+stack, R11 \ 175 | ADCQ 32+stack, R12 \ 176 | ADCQ 40+stack, R13 \ 177 | ADCQ 48+stack, R14 \ 178 | ADCQ 56+stack, R15 \ 179 | ADCQ $0, AX \ 180 | \ 181 | gfpCarry(R12,R13,R14,R15,AX, R8,R9,R10,R11,BX) 182 | -------------------------------------------------------------------------------- /elliptic/sm9curve/gfp.go: -------------------------------------------------------------------------------- 1 | package sm9curve 2 | 3 | import ( 4 | "crypto/sha256" 5 | "encoding/binary" 6 | "fmt" 7 | "math/big" 8 | 9 | "golang.org/x/crypto/hkdf" 10 | ) 11 | 12 | type gfP [4]uint64 13 | 14 | func newGFp(x int64) (out *gfP) { 15 | if x >= 0 { 16 | out = &gfP{uint64(x)} 17 | } else { 18 | out = &gfP{uint64(-x)} 19 | gfpNeg(out, out) 20 | } 21 | 22 | montEncode(out, out) 23 | return out 24 | } 25 | 26 | // hashToBase implements hashing a message to an element of the field. 27 | // 28 | // L = ceil((256+128)/8)=48, ctr = 0, i = 1 29 | func hashToBase(msg, dst []byte) *gfP { 30 | var t [48]byte 31 | info := []byte{'H', '2', 'C', byte(0), byte(1)} 32 | r := hkdf.New(sha256.New, msg, dst, info) 33 | if _, err := r.Read(t[:]); err != nil { 34 | panic(err) 35 | } 36 | var x big.Int 37 | v := x.SetBytes(t[:]).Mod(&x, p).Bytes() 38 | v32 := [32]byte{} 39 | for i := len(v) - 1; i >= 0; i-- { 40 | v32[len(v)-1-i] = v[i] 41 | } 42 | u := &gfP{ 43 | binary.LittleEndian.Uint64(v32[0*8 : 1*8]), 44 | binary.LittleEndian.Uint64(v32[1*8 : 2*8]), 45 | binary.LittleEndian.Uint64(v32[2*8 : 3*8]), 46 | binary.LittleEndian.Uint64(v32[3*8 : 4*8]), 47 | } 48 | montEncode(u, u) 49 | return u 50 | } 51 | 52 | func (e *gfP) String() string { 53 | return fmt.Sprintf("%16.16x%16.16x%16.16x%16.16x", e[3], e[2], e[1], e[0]) 54 | } 55 | 56 | func (e *gfP) Set(f *gfP) { 57 | e[0] = f[0] 58 | e[1] = f[1] 59 | e[2] = f[2] 60 | e[3] = f[3] 61 | } 62 | 63 | func (e *gfP) exp(f *gfP, bits [4]uint64) { 64 | sum, power := &gfP{}, &gfP{} 65 | sum.Set(rN1) 66 | power.Set(f) 67 | 68 | for word := 0; word < 4; word++ { 69 | for bit := uint(0); bit < 64; bit++ { 70 | if (bits[word]>>bit)&1 == 1 { 71 | gfpMul(sum, sum, power) 72 | } 73 | gfpMul(power, power, power) 74 | } 75 | } 76 | 77 | gfpMul(sum, sum, r3) 78 | e.Set(sum) 79 | } 80 | 81 | func (e *gfP) Invert(f *gfP) { 82 | e.exp(f, pMinus2) 83 | } 84 | 85 | func (e *gfP) Sqrt(f *gfP) { 86 | // Since p = 8k+5, 87 | // if f^((k+1)/4) = 1 mod p, then 88 | // e = f^(k+1) is a root of f; 89 | //else if f^((k+1)/4) = -1 mod p, then 90 | //e = 2^(2k+1)*f^(k+1) is a root of f. 91 | one := newGFp(1) 92 | tmp := new(gfP) 93 | tmp.exp(f, pMinus1Over4) 94 | 95 | if *tmp == *one { 96 | e.exp(f, pPlus3Over4) 97 | } else if *tmp == pMinus1 { 98 | e.exp(f, pPlus3Over4) 99 | gfpMul(e, e, &twoTo2kPlus1) 100 | } 101 | } 102 | 103 | func (e *gfP) Marshal(out []byte) { 104 | for w := uint(0); w < 4; w++ { 105 | for b := uint(0); b < 8; b++ { 106 | out[8*w+b] = byte(e[3-w] >> (56 - 8*b)) 107 | } 108 | } 109 | } 110 | 111 | func (e *gfP) Unmarshal(in []byte) { 112 | for w := uint(0); w < 4; w++ { 113 | e[3-w] = 0 114 | for b := uint(0); b < 8; b++ { 115 | e[3-w] += uint64(in[8*w+b]) << (56 - 8*b) 116 | } 117 | } 118 | } 119 | 120 | func montEncode(c, a *gfP) { gfpMul(c, a, r2) } 121 | func montDecode(c, a *gfP) { gfpMul(c, a, &gfP{1}) } 122 | 123 | func sign0(e *gfP) int { 124 | x := &gfP{} 125 | montDecode(x, e) 126 | for w := 3; w >= 0; w-- { 127 | if x[w] > pMinus1Over2[w] { 128 | return 1 129 | } else if x[w] < pMinus1Over2[w] { 130 | return -1 131 | } 132 | } 133 | return 1 134 | } 135 | 136 | func legendre(e *gfP) int { 137 | f := &gfP{} 138 | // Since p = 8k+5, then e^(4k+2) is the Legendre symbol of e. 139 | f.exp(e, pMinus1Over2) 140 | 141 | montDecode(f, f) 142 | 143 | if *f != [4]uint64{} { 144 | return 2*int(f[0]&1) - 1 145 | } 146 | 147 | return 0 148 | } 149 | 150 | func (c *gfP) Println() { 151 | fmt.Print("&gfP{") 152 | y, _ := new(big.Int).SetString(c.String(), 16) 153 | words := y.Bits() 154 | for _, word := range words[:len(words)-1] { 155 | fmt.Printf("%#x, ", word) 156 | } 157 | fmt.Printf("%#x}\n\n", words[len(words)-1]) 158 | } 159 | 160 | func gfpFromString(s string) gfP { 161 | y, _ := new(big.Int).SetString(s, 16) 162 | words := y.Bits() 163 | var a = gfP{} 164 | for i := 0; i < len(words); i++ { 165 | a[i] = uint64(words[i]) 166 | } 167 | return a 168 | } 169 | -------------------------------------------------------------------------------- /elliptic/sm9curve/gfp2.go: -------------------------------------------------------------------------------- 1 | package sm9curve 2 | 3 | import "math/big" 4 | 5 | // For details of the algorithms used, see "Multiplication and Squaring on 6 | // Pairing-Friendly Fields, Devegili et al. 7 | // http://eprint.iacr.org/2006/471.pdf. 8 | 9 | // gfP2 implements a field of size p² as a quadratic extension of the base field 10 | // where i²=-2. 11 | type gfP2 struct { 12 | x, y gfP // value is xi+y. 13 | } 14 | 15 | func gfP2Decode(in *gfP2) *gfP2 { 16 | out := &gfP2{} 17 | montDecode(&out.x, &in.x) 18 | montDecode(&out.y, &in.y) 19 | return out 20 | } 21 | 22 | func (e *gfP2) String() string { 23 | return "(" + e.x.String() + ", " + e.y.String() + ")" 24 | } 25 | 26 | func (e *gfP2) Set(a *gfP2) *gfP2 { 27 | e.x.Set(&a.x) 28 | e.y.Set(&a.y) 29 | return e 30 | } 31 | 32 | func (e *gfP2) SetZero() *gfP2 { 33 | e.x = gfP{0} 34 | e.y = gfP{0} 35 | return e 36 | } 37 | 38 | func (e *gfP2) SetOne() *gfP2 { 39 | e.x = gfP{0} 40 | e.y = *newGFp(1) 41 | return e 42 | } 43 | 44 | func (e *gfP2) IsZero() bool { 45 | zero := gfP{0} 46 | return e.x == zero && e.y == zero 47 | } 48 | 49 | func (e *gfP2) IsOne() bool { 50 | zero, one := gfP{0}, *newGFp(1) 51 | return e.x == zero && e.y == one 52 | } 53 | 54 | func (e *gfP2) Conjugate(a *gfP2) *gfP2 { 55 | e.y.Set(&a.y) 56 | gfpNeg(&e.x, &a.x) 57 | return e 58 | } 59 | 60 | func (e *gfP2) Neg(a *gfP2) *gfP2 { 61 | gfpNeg(&e.x, &a.x) 62 | gfpNeg(&e.y, &a.y) 63 | return e 64 | } 65 | 66 | func (e *gfP2) Add(a, b *gfP2) *gfP2 { 67 | gfpAdd(&e.x, &a.x, &b.x) 68 | gfpAdd(&e.y, &a.y, &b.y) 69 | return e 70 | } 71 | 72 | func (e *gfP2) Sub(a, b *gfP2) *gfP2 { 73 | gfpSub(&e.x, &a.x, &b.x) 74 | gfpSub(&e.y, &a.y, &b.y) 75 | return e 76 | } 77 | 78 | // See "Multiplication and Squaring in Pairing-Friendly Fields", 79 | // http://eprint.iacr.org/2006/471.pdf 80 | //(ai+b)(ci+d)=(bd-2ac)+i((a+b)(c+d)-ac-bd) 81 | func (e *gfP2) Mul(a, b *gfP2) *gfP2 { 82 | tx, t1, t2 := &gfP{}, &gfP{}, &gfP{} 83 | gfpAdd(t1, &a.x, &a.y) //a+b 84 | gfpAdd(t2, &b.x, &b.y) //c+d 85 | gfpMul(tx, t1, t2) 86 | 87 | gfpMul(t1, &a.x, &b.x) //ac 88 | gfpMul(t2, &a.y, &b.y) //bd 89 | gfpSub(tx, tx, t1) 90 | gfpSub(tx, tx, t2) //x=(a+b)(c+d)-ac-bd 91 | 92 | ty := &gfP{} 93 | gfpSub(ty, t2, t1) //bd-ac 94 | gfpSub(ty, ty, t1) //bd-2ac 95 | 96 | e.x.Set(tx) 97 | e.y.Set(ty) 98 | return e 99 | } 100 | 101 | func (e *gfP2) MulScalar(a *gfP2, b *gfP) *gfP2 { 102 | gfpMul(&e.x, &a.x, b) 103 | gfpMul(&e.y, &a.y, b) 104 | return e 105 | } 106 | 107 | // MulXi sets e=ξa where ξ=bi=(-1/2)i and then returns e. 108 | func (e *gfP2) MulXi(a *gfP2) *gfP2 { 109 | // (xi+y)bi = ybi-2bx=-1/2yi+x 110 | tx := &gfP{} 111 | ty := &gfP{} 112 | gfpMul(tx, &a.y, &bi) 113 | ty.Set(&a.x) 114 | 115 | e.x.Set(tx) 116 | e.y.Set(ty) 117 | return e 118 | } 119 | 120 | func (e *gfP2) Square(a *gfP2) *gfP2 { 121 | // Complex squaring algorithm: 122 | // (xi+y)² = (y²-2x²) + 2*i*x*y 123 | tx1, tx2, ty1, ty2 := &gfP{}, &gfP{}, &gfP{}, &gfP{} 124 | gfpMul(tx1, &a.x, &a.y) 125 | gfpAdd(tx2, tx1, tx1) 126 | 127 | gfpMul(ty1, &a.y, &a.y) 128 | gfpMul(ty2, &a.x, &a.x) 129 | ty := &gfP{} 130 | gfpAdd(ty, ty2, ty2) 131 | gfpSub(ty1, ty1, ty) 132 | 133 | e.x.Set(tx2) 134 | e.y.Set(ty1) 135 | return e 136 | } 137 | 138 | func (e *gfP2) Invert(a *gfP2) *gfP2 { 139 | // See "Implementing cryptographic pairings", M. Scott, section 3.2. 140 | // ftp://136.206.11.249/pub/crypto/pairings.pdf 141 | t1, t2 := &gfP{}, &gfP{} 142 | gfpMul(t1, &a.x, &a.x) 143 | t3 := &gfP{} 144 | gfpAdd(t3, t1, t1) 145 | gfpMul(t2, &a.y, &a.y) 146 | gfpAdd(t3, t3, t2) 147 | 148 | inv := &gfP{} 149 | inv.Invert(t3) 150 | 151 | gfpNeg(t1, &a.x) 152 | 153 | gfpMul(&e.x, t1, inv) 154 | gfpMul(&e.y, &a.y, inv) 155 | return e 156 | } 157 | 158 | func (c *gfP2) GFp2Exp(a *gfP2, b *big.Int) *gfP2 { 159 | sum := (&gfP2{}).SetOne() 160 | t := &gfP2{} 161 | 162 | for i := b.BitLen() - 1; i >= 0; i-- { 163 | t.Square(sum) 164 | if b.Bit(i) != 0 { 165 | sum.Mul(t, a) 166 | } else { 167 | sum.Set(t) 168 | } 169 | } 170 | 171 | c.Set(sum) 172 | return c 173 | } 174 | -------------------------------------------------------------------------------- /elliptic/sm9curve/gfp_generic.go: -------------------------------------------------------------------------------- 1 | //go:build (!amd64 && arm64) || generic 2 | // +build !amd64,arm64 generic 3 | 4 | package sm9curve 5 | 6 | func gfpCarry(a *gfP, head uint64) { 7 | b := &gfP{} 8 | 9 | var carry uint64 10 | for i, pi := range p2 { 11 | ai := a[i] 12 | bi := ai - pi - carry 13 | b[i] = bi 14 | carry = (pi&^ai | (pi|^ai)&bi) >> 63 15 | } 16 | carry = carry &^ head 17 | 18 | // If b is negative, then return a. 19 | // Else return b. 20 | carry = -carry 21 | ncarry := ^carry 22 | for i := 0; i < 4; i++ { 23 | a[i] = (a[i] & carry) | (b[i] & ncarry) 24 | } 25 | } 26 | 27 | func gfpNeg(c, a *gfP) { 28 | var carry uint64 29 | for i, pi := range p2 { 30 | ai := a[i] 31 | ci := pi - ai - carry 32 | c[i] = ci 33 | carry = (ai&^pi | (ai|^pi)&ci) >> 63 34 | } 35 | gfpCarry(c, 0) 36 | } 37 | 38 | func gfpAdd(c, a, b *gfP) { 39 | var carry uint64 40 | for i, ai := range a { 41 | bi := b[i] 42 | ci := ai + bi + carry 43 | c[i] = ci 44 | carry = (ai&bi | (ai|bi)&^ci) >> 63 45 | } 46 | gfpCarry(c, carry) 47 | } 48 | 49 | func gfpSub(c, a, b *gfP) { 50 | t := &gfP{} 51 | 52 | var carry uint64 53 | for i, pi := range p2 { 54 | bi := b[i] 55 | ti := pi - bi - carry 56 | t[i] = ti 57 | carry = (bi&^pi | (bi|^pi)&ti) >> 63 58 | } 59 | 60 | carry = 0 61 | for i, ai := range a { 62 | ti := t[i] 63 | ci := ai + ti + carry 64 | c[i] = ci 65 | carry = (ai&ti | (ai|ti)&^ci) >> 63 66 | } 67 | gfpCarry(c, carry) 68 | } 69 | 70 | func mul(a, b [4]uint64) [8]uint64 { 71 | const ( 72 | mask16 uint64 = 0x0000ffff 73 | mask32 uint64 = 0xffffffff 74 | ) 75 | 76 | var buff [32]uint64 77 | for i, ai := range a { 78 | a0, a1, a2, a3 := ai&mask16, (ai>>16)&mask16, (ai>>32)&mask16, ai>>48 79 | 80 | for j, bj := range b { 81 | b0, b2 := bj&mask32, bj>>32 82 | 83 | off := 4 * (i + j) 84 | buff[off+0] += a0 * b0 85 | buff[off+1] += a1 * b0 86 | buff[off+2] += a2*b0 + a0*b2 87 | buff[off+3] += a3*b0 + a1*b2 88 | buff[off+4] += a2 * b2 89 | buff[off+5] += a3 * b2 90 | } 91 | } 92 | 93 | for i := uint(1); i < 4; i++ { 94 | shift := 16 * i 95 | 96 | var head, carry uint64 97 | for j := uint(0); j < 8; j++ { 98 | block := 4 * j 99 | 100 | xi := buff[block] 101 | yi := (buff[block+i] << shift) + head 102 | zi := xi + yi + carry 103 | buff[block] = zi 104 | carry = (xi&yi | (xi|yi)&^zi) >> 63 105 | 106 | head = buff[block+i] >> (64 - shift) 107 | } 108 | } 109 | 110 | return [8]uint64{buff[0], buff[4], buff[8], buff[12], buff[16], buff[20], buff[24], buff[28]} 111 | } 112 | 113 | func halfMul(a, b [4]uint64) [4]uint64 { 114 | const ( 115 | mask16 uint64 = 0x0000ffff 116 | mask32 uint64 = 0xffffffff 117 | ) 118 | 119 | var buff [18]uint64 120 | for i, ai := range a { 121 | a0, a1, a2, a3 := ai&mask16, (ai>>16)&mask16, (ai>>32)&mask16, ai>>48 122 | 123 | for j, bj := range b { 124 | if i+j > 3 { 125 | break 126 | } 127 | b0, b2 := bj&mask32, bj>>32 128 | 129 | off := 4 * (i + j) 130 | buff[off+0] += a0 * b0 131 | buff[off+1] += a1 * b0 132 | buff[off+2] += a2*b0 + a0*b2 133 | buff[off+3] += a3*b0 + a1*b2 134 | buff[off+4] += a2 * b2 135 | buff[off+5] += a3 * b2 136 | } 137 | } 138 | 139 | for i := uint(1); i < 4; i++ { 140 | shift := 16 * i 141 | 142 | var head, carry uint64 143 | for j := uint(0); j < 4; j++ { 144 | block := 4 * j 145 | 146 | xi := buff[block] 147 | yi := (buff[block+i] << shift) + head 148 | zi := xi + yi + carry 149 | buff[block] = zi 150 | carry = (xi&yi | (xi|yi)&^zi) >> 63 151 | 152 | head = buff[block+i] >> (64 - shift) 153 | } 154 | } 155 | 156 | return [4]uint64{buff[0], buff[4], buff[8], buff[12]} 157 | } 158 | 159 | func gfpMul(c, a, b *gfP) { 160 | T := mul(*a, *b) 161 | m := halfMul([4]uint64{T[0], T[1], T[2], T[3]}, np) 162 | t := mul([4]uint64{m[0], m[1], m[2], m[3]}, p2) 163 | 164 | var carry uint64 165 | for i, Ti := range T { 166 | ti := t[i] 167 | zi := Ti + ti + carry 168 | T[i] = zi 169 | carry = (Ti&ti | (Ti|ti)&^zi) >> 63 170 | } 171 | 172 | *c = gfP{T[4], T[5], T[6], T[7]} 173 | gfpCarry(c, carry) 174 | } 175 | -------------------------------------------------------------------------------- /sm/sm3/sm3hash.go: -------------------------------------------------------------------------------- 1 | //Copyright 2020 cetc-30. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package sm3 6 | 7 | func leftRotate(x uint32, r uint32) uint32 { return (x<<(r%32) | x>>(32-r%32)) } 8 | 9 | func ff0(X uint32, Y uint32, Z uint32) uint32 { return X ^ Y ^ Z } 10 | func ff1(X uint32, Y uint32, Z uint32) uint32 { return (X & Y) | (X & Z) | (Y & Z) } 11 | 12 | func gg0(X uint32, Y uint32, Z uint32) uint32 { return X ^ Y ^ Z } 13 | func gg1(X uint32, Y uint32, Z uint32) uint32 { return (X & Y) | ((^X) & Z) } 14 | 15 | func p0(X uint32) uint32 { return X ^ leftRotate(X, 9) ^ leftRotate(X, 17) } 16 | 17 | func p1(X uint32) uint32 { return X ^ leftRotate(X, 15) ^ leftRotate(X, 23) } 18 | 19 | func msgPadding(message []byte) []byte { 20 | // Pre-processing: 21 | chunk := message 22 | 23 | // Pre-processing: adding a single 1 bit 24 | chunk = append(chunk, byte(0x80)) 25 | 26 | // Pre-processing: padding with zeros 27 | padding := 56 - len(chunk)%64 28 | for i := 0; i < padding; i++ { 29 | chunk = append(chunk, 0x00) 30 | } 31 | var l uint64 32 | l = uint64(len(message) * 8) 33 | 34 | // l := byte((len(message) * 8))() 35 | chunk = append(chunk, byte((l>>56)&0xff)) 36 | chunk = append(chunk, byte((l>>48)&0xff)) 37 | chunk = append(chunk, byte((l>>40)&0xff)) 38 | chunk = append(chunk, byte((l>>32)&0xff)) 39 | chunk = append(chunk, byte((l>>24)&0xff)) 40 | chunk = append(chunk, byte((l>>16)&0xff)) 41 | chunk = append(chunk, byte((l>>8)&0xff)) 42 | chunk = append(chunk, byte(l&0xff)) 43 | 44 | // hstr := biu.BytesToHexString(chunk) 45 | // fmt.Println(len(hstr)) 46 | // fmt.Println("test" + hstr) 47 | 48 | // return hstr 49 | return chunk 50 | } 51 | 52 | type W struct { 53 | W1 [68]uint32 54 | W2 [64]uint32 55 | } 56 | 57 | func msgExp(x [16]uint32) W { 58 | var i int 59 | var wtmp W 60 | for i = 0; i < 16; i++ { 61 | wtmp.W1[i] = x[i] 62 | } 63 | for i = 16; i < 68; i++ { 64 | wtmp.W1[i] = p1(wtmp.W1[i-16]^wtmp.W1[i-9]^leftRotate(wtmp.W1[i-3], 15)) ^ leftRotate(wtmp.W1[i-13], 7) ^ wtmp.W1[i-6] 65 | } 66 | for i = 0; i < 64; i++ { 67 | wtmp.W2[i] = wtmp.W1[i] ^ wtmp.W1[i+4] 68 | } 69 | return wtmp 70 | } 71 | 72 | func cF(V [8]uint32, Bmsg [16]uint32) [8]uint32 { 73 | var j int 74 | var A, B, C, D, E, F, G, H uint32 75 | A = V[0] 76 | B = V[1] 77 | C = V[2] 78 | D = V[3] 79 | E = V[4] 80 | F = V[5] 81 | G = V[6] 82 | H = V[7] 83 | wtmp := msgExp(Bmsg) 84 | for j = 0; j < 16; j++ { 85 | var jj int 86 | if j < 33 { 87 | jj = j 88 | } else { 89 | jj = j - 32 90 | } 91 | SS1 := leftRotate(leftRotate(A, 12)+E+leftRotate(0x79cc4519, uint32(jj)), 7) 92 | SS2 := SS1 ^ leftRotate(A, 12) 93 | TT1 := ff0(A, B, C) + D + SS2 + wtmp.W2[j] 94 | TT2 := gg0(E, F, G) + H + SS1 + wtmp.W1[j] 95 | D = C 96 | C = leftRotate(B, 9) 97 | B = A 98 | A = TT1 99 | H = G 100 | G = leftRotate(F, 19) 101 | F = E 102 | E = p0(TT2) 103 | } 104 | for j = 16; j < 64; j++ { 105 | var jj int 106 | if j < 33 { 107 | jj = j 108 | } else { 109 | jj = j - 32 110 | } 111 | SS1 := leftRotate(leftRotate(A, 12)+E+leftRotate(0x7a879d8a, uint32(jj)), 7) 112 | SS2 := SS1 ^ leftRotate(A, 12) 113 | TT1 := ff1(A, B, C) + D + SS2 + wtmp.W2[j] 114 | TT2 := gg1(E, F, G) + H + SS1 + wtmp.W1[j] 115 | D = C 116 | C = leftRotate(B, 9) 117 | B = A 118 | A = TT1 119 | H = G 120 | G = leftRotate(F, 19) 121 | F = E 122 | E = p0(TT2) 123 | } 124 | 125 | V[0] = A ^ V[0] 126 | V[1] = B ^ V[1] 127 | V[2] = C ^ V[2] 128 | V[3] = D ^ V[3] 129 | V[4] = E ^ V[4] 130 | V[5] = F ^ V[5] 131 | V[6] = G ^ V[6] 132 | V[7] = H ^ V[7] 133 | 134 | return V 135 | } 136 | 137 | func Block(dig *digest, p []byte) { 138 | var V [8]uint32 139 | for i := 0; i < 8; i++ { 140 | V[i] = dig.h[i] 141 | } 142 | for len(p) >= 64 { 143 | m := [16]uint32{} 144 | x := p[:64] 145 | xi := 0 146 | mi := 0 147 | for mi < 16 { 148 | m[mi] = (uint32(x[xi+3]) | 149 | (uint32(x[xi+2]) << 8) | 150 | (uint32(x[xi+1]) << 16) | 151 | (uint32(x[xi]) << 24)) 152 | mi += 1 153 | xi += 4 154 | } 155 | V = cF(V, m) 156 | p = p[64:] 157 | } 158 | for i := 0; i < 8; i++ { 159 | dig.h[i] = V[i] 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /elliptic/sm9curve/constants.go: -------------------------------------------------------------------------------- 1 | package sm9curve 2 | 3 | import ( 4 | "math/big" 5 | ) 6 | 7 | func bigFromBase10(s string) *big.Int { 8 | n, _ := new(big.Int).SetString(s, 10) 9 | return n 10 | } 11 | 12 | // u is the BN parameter that determines the prime: 600000000058f98a. 13 | var u, _ = new(big.Int).SetString("600000000058f98a", 16) 14 | 15 | // p is a prime over which we form a basic field: 36u⁴+36u³+24u²+6u+1. 16 | var p, _ = new(big.Int).SetString("b640000002a3a6f1d603ab4ff58ec74521f2934b1a7aeedbe56f9b27e351457d", 16) 17 | 18 | // Order is the number of elements in both G₁ and G₂: 36u⁴+36u³+18u²+6u+1. 19 | var Order, _ = new(big.Int).SetString("b640000002a3a6f1d603ab4ff58ec74449f2934b18ea8beee56ee19cd69ecf25", 16) 20 | 21 | //gx,gy are coordinates of G1 in montEncode form 22 | //var gx = gfP{0x22e935e29860501b,0xa946fd5e0073282c,0xefd0cec817a649be,0x5129787c869140b5} 23 | //var gy = gfP{0xee779649eb87f7c7,0x15563cbdec30a576,0x326353912824efbf,0x7215717763c39828} 24 | 25 | // p2 is p, represented as little-endian 64-bit words. 26 | var p2 = [4]uint64{0xe56f9b27e351457d, 0x21f2934b1a7aeedb, 0xd603ab4ff58ec745, 0xb640000002a3a6f1} 27 | 28 | // np is the negative inverse of p, mod 2^256. 29 | var np = [4]uint64{0x892bc42c2f2ee42b, 0x181ae39613c8dbaf, 0x966a4b291522b137, 0xafd2bac5558a13b3} 30 | 31 | // rN1 is R^-1 where R = 2^256 mod p. 32 | var rN1 = &gfP{0x0a1c7970e5df544d, 0xe74504e9a96b56cc, 0xcda02d92d4d62924, 0x7d2bc576fdf597d1} 33 | 34 | // r2 is R^2 where R = 2^256 mod p. 35 | var r2 = &gfP{0x27dea312b417e2d2, 0x88f8105fae1a5d3f, 0xe479b522d6706e7b, 0x2ea795a656f62fbd} 36 | 37 | // r3 is R^3 where R = 2^256 mod p. 38 | var r3 = &gfP{0x130257769df5827e, 0x36920fc0837ec76e, 0xcbec24519c22a142, 0x219be84a7c687090} 39 | 40 | // pPlus1Over4 is (p+1)/4. 41 | var pPlus1Over4 = [4]uint64{0xf95be6c9f8d4515f, 0x487ca4d2c69ebbb6, 0x7580ead3fd63b1d1, 0x2d90000000a8e9bc} 42 | 43 | //pPlus3Over4 is (p+3)/4 44 | var pPlus3Over4 = [4]uint64{0xf95be6c9f8d45160, 0x487ca4d2c69ebbb6, 0x7580ead3fd63b1d1, 0x2d90000000a8e9bc} 45 | 46 | //twoTo2kPlus1 is 2^(2k+1),where k = (p-1)/4 47 | var twoTo2kPlus1 = gfP{0xe56f9b27e351457c, 0x21f2934b1a7aeedb, 0xd603ab4ff58ec745, 0xb640000002a3a6f1} 48 | 49 | //pMinus1 is p-1 50 | var pMinus1 = gfP{0xcadf364fc6a28afa, 0x43e5269634f5ddb7, 0xac07569feb1d8e8a, 0x6c80000005474de3} 51 | 52 | // pMinus2 is p-2. 53 | var pMinus2 = [4]uint64{0xe56f9b27e351457b, 0x21f2934b1a7aeedb, 0xd603ab4ff58ec745, 0xb640000002a3a6f1} 54 | 55 | // pMinus1Over2 is (p-1)/2. 56 | var pMinus1Over2 = [4]uint64{0xf2b7cd93f1a8a2be, 0x90f949a58d3d776d, 0xeb01d5a7fac763a2, 0x5b2000000151d378} 57 | 58 | // pMinus1Over2 is (p-1)/4. 59 | var pMinus1Over4 = [4]uint64{0xf95be6c9f8d4515f, 0x487ca4d2c69ebbb6, 0x7580ead3fd63b1d1, 0x2d90000000a8e9bc} 60 | 61 | //ξ=bi, b = (-1/2) mod p (in montEncode form). 62 | //var b = gfP{0xf2b7cd93f1a8a2be,0x90f949a58d3d776d,0xeb01d5a7fac763a2,0x5b2000000151d378} 63 | var bi = gfP{0xe56f9b27e351457d, 0x21f2934b1a7aeedb, 0xd603ab4ff58ec745, 0x3640000002a3a6f1} 64 | 65 | // s is the Montgomery encoding of the square root of -3. Then, s = sqrt(-3) * 2^256 mod p. 66 | var s = &gfP{0x7b2e07c770965b71, 0xa9bce0778466aa4b, 0x2e12588fcbc9e459, 0x8f4000000d3242b9} 67 | 68 | // sMinus1Over2 is the Montgomery encoding of (s-1)/2. Then, sMinus1Over2 = ( (s-1) / 2) * 2^256 mod p. 69 | var sMinus1Over2 = &gfP{0xb04ed177a9f3d077, 0x65d7b9e14f70cc93, 0x820b01efe0ac55cf, 0x22c0000007eaf4d5} 70 | 71 | // xiToPMinus1Over2 is ξ^((p-1)/2) where ξ = (-1/2)i. 72 | var xiToPMinus1Over2 = &gfP{0xabbaac18a46a2054, 0x46ee57561222c759, 0x1dae609fa0e23561, 0x1df7113dae0adc3c} 73 | 74 | // xiToPMinus1Over3 is ξ^((p-1)/3) where ξ = (-1/2)i. 75 | var xiToPMinus1Over3 = &gfP{0x646a4b5a4e6783b9, 0xd5e4017f8d980f9d, 0x8d8bf6fd0cdfe790, 0x2d4ac18b775a8f7b} 76 | 77 | // xiTo2PMinus2Over3 is ξ^((2p-2)/3) where ξ = (-1/2)i. 78 | var xiTo2PMinus2Over3 = &gfP{0x2f4981aa150a0eb3, 0x19c92815c28ded55, 0x39934d9cf7fd761b, 0x99cac18b7ca1dd5f} 79 | 80 | // xiToPMinus1Over6 is ξ^((p-1)/6) where ξ = (-1/2)i. 81 | var xiToPMinus1Over6 = &gfP{0xe0e3f0ae068e0476, 0xc3c418861c042d7a, 0x3cca13fbbf32f288, 0x6ae5153810898de} 82 | 83 | // xiToPSquaredMinus1Over3 is ξ^((p²-1)/3) where ξ = (-1/2)i. 84 | var xiToPSquaredMinus1Over3 = &gfP{0x2f4981aa150a0eb3, 0x19c92815c28ded55, 0x39934d9cf7fd761b, 0x99cac18b7ca1dd5f} 85 | 86 | // xiTo2PSquaredMinus2Over3 is ξ^((2p²-2)/3) where ξ = (-1/2)i. 87 | var xiTo2PSquaredMinus2Over3 = &gfP{0x81054fcd94e9c1c4, 0x4c0e91cb8ce2df3e, 0x4877b452e8aedfb4, 0x88f53e748b491776} 88 | 89 | // xiToPSquaredMinus1Over6 is ξ^((1p²-1)/6) where ξ = (-1/2)i. 90 | var xiToPSquaredMinus1Over6 = &gfP{0x646a4b5a4e6783b9, 0xd5e4017f8d980f9d, 0x8d8bf6fd0cdfe790, 0x2d4ac18b775a8f7b} 91 | -------------------------------------------------------------------------------- /elliptic/sm9curve/twist.go: -------------------------------------------------------------------------------- 1 | package sm9curve 2 | 3 | import ( 4 | "math/big" 5 | ) 6 | 7 | // twistPoint implements the elliptic curve y²=x³+5/ξ over GF(p²). Points are 8 | // kept in Jacobian form and t=z² when valid. The group G₂ is the set of 9 | // n-torsion points of this curve over GF(p²) (where n = Order) 10 | type twistPoint struct { 11 | x, y, z, t gfP2 12 | } 13 | 14 | var twistB = &gfP2{ 15 | *newGFp(5), 16 | *newGFp(0), 17 | } 18 | 19 | // twistGen is the generator of group G₂ (in form of montEncode). 20 | var twistGen = &twistPoint{ 21 | gfP2{ 22 | gfP{0xdb6db4822750a8a6, 0x84c6135a5121f134, 0x1874032f88791d41, 0x905112f2b85f3a37}, 23 | gfP{0x260226a68ce2da8f, 0x7ee5645edbf6c06b, 0xf8f57c82b1495444, 0x61fcf018bc47c4d1}, 24 | }, 25 | gfP2{ 26 | gfP{0xf7b82dac4c89bfbb, 0x3706f3f6a49dc12f, 0x1e29de93d3eef769, 0x81e448c3c76a5d53}, 27 | gfP{0xc03f138f9171c24a, 0x92fbab45a15a3ca7, 0x2445561e2ff77cdb, 0x108495e0c0f62ece}, 28 | }, 29 | gfP2{*newGFp(0), *newGFp(1)}, 30 | gfP2{*newGFp(0), *newGFp(1)}, 31 | } 32 | 33 | func (c *twistPoint) String() string { 34 | c.MakeAffine() 35 | x, y := gfP2Decode(&c.x), gfP2Decode(&c.y) 36 | return "(" + x.String() + ", " + y.String() + ")" 37 | } 38 | 39 | func (c *twistPoint) Set(a *twistPoint) { 40 | c.x.Set(&a.x) 41 | c.y.Set(&a.y) 42 | c.z.Set(&a.z) 43 | c.t.Set(&a.t) 44 | } 45 | 46 | // IsOnCurve returns true iff c is on the curve. 47 | func (c *twistPoint) IsOnCurve() bool { 48 | c.MakeAffine() 49 | if c.IsInfinity() { 50 | return true 51 | } 52 | 53 | y2, x3 := &gfP2{}, &gfP2{} 54 | y2.Square(&c.y) 55 | x3.Square(&c.x).Mul(x3, &c.x).Add(x3, twistB) 56 | 57 | return *y2 == *x3 58 | } 59 | 60 | func (c *twistPoint) SetInfinity() { 61 | c.x.SetZero() 62 | c.y.SetOne() 63 | c.z.SetZero() 64 | c.t.SetZero() 65 | } 66 | 67 | func (c *twistPoint) IsInfinity() bool { 68 | return c.z.IsZero() 69 | } 70 | 71 | func (c *twistPoint) Add(a, b *twistPoint) { 72 | // For additional comments, see the same function in curve.go. 73 | 74 | if a.IsInfinity() { 75 | c.Set(b) 76 | return 77 | } 78 | if b.IsInfinity() { 79 | c.Set(a) 80 | return 81 | } 82 | 83 | // See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/addition/add-2007-bl.op3 84 | z12 := (&gfP2{}).Square(&a.z) 85 | z22 := (&gfP2{}).Square(&b.z) 86 | u1 := (&gfP2{}).Mul(&a.x, z22) 87 | u2 := (&gfP2{}).Mul(&b.x, z12) 88 | 89 | t := (&gfP2{}).Mul(&b.z, z22) 90 | s1 := (&gfP2{}).Mul(&a.y, t) 91 | 92 | t.Mul(&a.z, z12) 93 | s2 := (&gfP2{}).Mul(&b.y, t) 94 | 95 | h := (&gfP2{}).Sub(u2, u1) 96 | xEqual := h.IsZero() 97 | 98 | t.Add(h, h) 99 | i := (&gfP2{}).Square(t) 100 | j := (&gfP2{}).Mul(h, i) 101 | 102 | t.Sub(s2, s1) 103 | yEqual := t.IsZero() 104 | if xEqual && yEqual { 105 | c.Double(a) 106 | return 107 | } 108 | r := (&gfP2{}).Add(t, t) 109 | 110 | v := (&gfP2{}).Mul(u1, i) 111 | 112 | t4 := (&gfP2{}).Square(r) 113 | t.Add(v, v) 114 | t6 := (&gfP2{}).Sub(t4, j) 115 | c.x.Sub(t6, t) 116 | 117 | t.Sub(v, &c.x) // t7 118 | t4.Mul(s1, j) // t8 119 | t6.Add(t4, t4) // t9 120 | t4.Mul(r, t) // t10 121 | c.y.Sub(t4, t6) 122 | 123 | t.Add(&a.z, &b.z) // t11 124 | t4.Square(t) // t12 125 | t.Sub(t4, z12) // t13 126 | t4.Sub(t, z22) // t14 127 | c.z.Mul(t4, h) 128 | } 129 | 130 | func (c *twistPoint) Double(a *twistPoint) { 131 | // See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/doubling/dbl-2009-l.op3 132 | A := (&gfP2{}).Square(&a.x) 133 | B := (&gfP2{}).Square(&a.y) 134 | C := (&gfP2{}).Square(B) 135 | 136 | t := (&gfP2{}).Add(&a.x, B) 137 | t2 := (&gfP2{}).Square(t) 138 | t.Sub(t2, A) 139 | t2.Sub(t, C) 140 | d := (&gfP2{}).Add(t2, t2) 141 | t.Add(A, A) 142 | e := (&gfP2{}).Add(t, A) 143 | f := (&gfP2{}).Square(e) 144 | 145 | t.Add(d, d) 146 | c.x.Sub(f, t) 147 | 148 | c.z.Mul(&a.y, &a.z) 149 | c.z.Add(&c.z, &c.z) 150 | 151 | t.Add(C, C) 152 | t2.Add(t, t) 153 | t.Add(t2, t2) 154 | c.y.Sub(d, &c.x) 155 | t2.Mul(e, &c.y) 156 | c.y.Sub(t2, t) 157 | } 158 | 159 | func (c *twistPoint) Mul(a *twistPoint, scalar *big.Int) { 160 | sum, t := &twistPoint{}, &twistPoint{} 161 | 162 | for i := scalar.BitLen(); i >= 0; i-- { 163 | t.Double(sum) 164 | if scalar.Bit(i) != 0 { 165 | sum.Add(t, a) 166 | } else { 167 | sum.Set(t) 168 | } 169 | } 170 | 171 | c.Set(sum) 172 | } 173 | 174 | func (c *twistPoint) MakeAffine() { 175 | if c.z.IsOne() { 176 | return 177 | } else if c.z.IsZero() { 178 | c.x.SetZero() 179 | c.y.SetOne() 180 | c.t.SetZero() 181 | return 182 | } 183 | 184 | zInv := (&gfP2{}).Invert(&c.z) 185 | t := (&gfP2{}).Mul(&c.y, zInv) 186 | zInv2 := (&gfP2{}).Square(zInv) 187 | c.y.Mul(t, zInv2) 188 | t.Mul(&c.x, zInv2) 189 | c.x.Set(t) 190 | c.z.SetOne() 191 | c.t.SetOne() 192 | } 193 | 194 | func (c *twistPoint) Neg(a *twistPoint) { 195 | c.x.Set(&a.x) 196 | c.y.Neg(&a.y) 197 | c.z.Set(&a.z) 198 | c.t.SetZero() 199 | } 200 | -------------------------------------------------------------------------------- /sm/sm2/sm2enc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 cetc-30. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package sm2 6 | 7 | import ( 8 | "bytes" 9 | "encoding/binary" 10 | "errors" 11 | "github.com/xlcetc/cryptogm/sm/sm3" 12 | "io" 13 | "math" 14 | "math/big" 15 | ) 16 | 17 | var EncryptionErr = errors.New("sm2: encryption error") 18 | var DecryptionErr = errors.New("sm2: decryption error") 19 | 20 | func keyDerivation(Z []byte, klen int) []byte { 21 | var ct = 1 22 | if klen%8 != 0 { 23 | return nil 24 | } 25 | 26 | K := make([]byte, int(math.Ceil(float64(klen)/(sm3.Size*8))*sm3.Size)) 27 | v := sm3.Size * 8 28 | 29 | l := int(math.Ceil(float64(klen) / float64(v))) 30 | 31 | var m = make([]byte, len(Z)+4) 32 | var vBytes = make([]byte, 4) 33 | copy(m, Z) 34 | 35 | for ; ct <= l; ct++ { 36 | binary.BigEndian.PutUint32(vBytes, uint32(ct)) 37 | copy(m[len(Z):], vBytes) 38 | 39 | hash := sm3.SumSM3(m) 40 | copy(K[(ct-1)*sm3.Size:], hash[:]) 41 | } 42 | return K[:klen/8] 43 | } 44 | 45 | func Encrypt(rand io.Reader, key *PublicKey, msg []byte) (cipher []byte, err error) { 46 | x, y, c2, c3, err := doEncrypt(rand, key, msg) 47 | if err != nil { 48 | return nil, err 49 | } 50 | 51 | c1 := pointToBytes(x, y) 52 | 53 | //c = c1||c2||c3,len(c1)=65,len(c3)=32 54 | cipher = append(c1, c2...) 55 | cipher = append(cipher, c3...) 56 | 57 | return 58 | } 59 | 60 | func doEncrypt(rand io.Reader, key *PublicKey, msg []byte) (x, y *big.Int, c2, c3 []byte, err error) { 61 | k := generateRandK(rand, key.Curve) 62 | 63 | regen: 64 | x1, y1 := key.Curve.ScalarBaseMult(k.Bytes()) 65 | 66 | var x2, y2 *big.Int 67 | if opt, ok := key.Curve.(optMethod); ok && (key.PreComputed != nil) { 68 | x2, y2 = opt.PreScalarMult(key.PreComputed, k.Bytes()) 69 | } else { 70 | x2, y2 = key.Curve.ScalarMult(key.X, key.Y, k.Bytes()) 71 | } 72 | 73 | xBuf := x2.Bytes() 74 | yBuf := y2.Bytes() 75 | 76 | xPadding := make([]byte, 32) 77 | yPadding := make([]byte, 32) 78 | if n := len(xBuf); n < 32 { 79 | xBuf = append(xPadding[:32-n], xBuf...) 80 | } 81 | 82 | if n := len(yBuf); n < 32 { 83 | yBuf = append(yPadding[:32-n], yBuf...) 84 | } 85 | 86 | //z=x2||y2 87 | Z := make([]byte, 64) 88 | copy(Z, xBuf) 89 | copy(Z[32:], yBuf) 90 | 91 | t := keyDerivation(Z, len(msg)*8) 92 | if t == nil { 93 | return nil, nil, nil, nil, EncryptionErr 94 | } 95 | for i, v := range t { 96 | if v != 0 { 97 | break 98 | } 99 | if i == len(t)-1 { 100 | goto regen 101 | } 102 | } 103 | 104 | //M^t 105 | for i, v := range t { 106 | t[i] = v ^ msg[i] 107 | } 108 | 109 | m3 := make([]byte, 64+len(msg)) 110 | copy(m3, xBuf) 111 | copy(m3[32:], msg) 112 | copy(m3[32+len(msg):], yBuf) 113 | h := sm3.SumSM3(m3) 114 | c3 = h[:] 115 | 116 | return x1, y1, t, c3, nil 117 | } 118 | 119 | func Decrypt(c []byte, key *PrivateKey) ([]byte, error) { 120 | x1, y1 := pointFromBytes(c[:65]) 121 | 122 | //dB*C1 123 | x2, y2 := key.Curve.ScalarMult(x1, y1, key.D.Bytes()) 124 | 125 | xBuf := x2.Bytes() 126 | yBuf := y2.Bytes() 127 | 128 | xPadding := make([]byte, 32) 129 | yPadding := make([]byte, 32) 130 | if n := len(xBuf); n < 32 { 131 | xBuf = append(xPadding[:32-n], xBuf...) 132 | } 133 | 134 | if n := len(yBuf); n < 32 { 135 | yBuf = append(yPadding[:32-n], yBuf...) 136 | } 137 | 138 | //z=x2||y2 139 | Z := make([]byte, 64) 140 | copy(Z, xBuf) 141 | copy(Z[32:], yBuf) 142 | 143 | t := keyDerivation(Z, (len(c)-97)*8) 144 | if t == nil { 145 | return nil, DecryptionErr 146 | } 147 | for i, v := range t { 148 | if v != 0 { 149 | break 150 | } 151 | if i == len(t)-1 { 152 | return nil, DecryptionErr 153 | } 154 | } 155 | 156 | // m` = c2 ^ t 157 | c2 := c[65:(len(c) - 32)] 158 | for i, v := range t { 159 | t[i] = v ^ c2[i] 160 | } 161 | 162 | //validate 163 | _u := make([]byte, 64+len(t)) 164 | copy(_u, xBuf) 165 | copy(_u[32:], t) 166 | copy(_u[32+len(t):], yBuf) 167 | u := sm3.SumSM3(_u) 168 | if !bytes.Equal(u[:], c[65+len(c2):]) { 169 | return nil, DecryptionErr 170 | } 171 | 172 | return t, nil 173 | } 174 | 175 | //uncompressed form, s=04||x||y 176 | func pointToBytes(x, y *big.Int) []byte { 177 | buf := []byte{} 178 | 179 | xBuf := x.Bytes() 180 | yBuf := y.Bytes() 181 | 182 | xPadding := make([]byte, 32) 183 | yPadding := make([]byte, 32) 184 | if n := len(xBuf); n < 32 { 185 | xBuf = append(xPadding[:32-n], xBuf...) 186 | } 187 | 188 | if n := len(yBuf); n < 32 { 189 | yBuf = append(yPadding[:32-n], yBuf...) 190 | } 191 | 192 | //s = 04||x||y 193 | buf = append(buf, 0x4) 194 | buf = append(buf, xBuf...) 195 | buf = append(buf, yBuf...) 196 | 197 | return buf 198 | } 199 | 200 | func pointFromBytes(buf []byte) (x, y *big.Int) { 201 | if len(buf) != 65 || buf[0] != 0x4 { 202 | return nil, nil 203 | } 204 | 205 | x = new(big.Int).SetBytes(buf[1:33]) 206 | y = new(big.Int).SetBytes(buf[33:]) 207 | 208 | return 209 | } 210 | -------------------------------------------------------------------------------- /sm/sm9/sm9.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 cetc-30. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package sm9 6 | 7 | import ( 8 | "crypto/rand" 9 | "encoding/binary" 10 | "github.com/pkg/errors" 11 | "github.com/xlcetc/cryptogm/elliptic/sm9curve" 12 | "github.com/xlcetc/cryptogm/sm/sm3" 13 | "io" 14 | "math" 15 | "math/big" 16 | ) 17 | 18 | type hashMode int 19 | 20 | const ( 21 | // hashmode used in h1: 0x01 22 | H1 hashMode = iota + 1 23 | // hashmode used in h2: 0x02 24 | H2 25 | ) 26 | 27 | //MasterKey contains a master secret key and a master public key. 28 | type MasterKey struct { 29 | Msk *big.Int 30 | MasterPubKey 31 | } 32 | 33 | type MasterPubKey struct { 34 | Mpk *sm9curve.G2 35 | } 36 | 37 | //UserKey contains a secret key. 38 | type UserKey struct { 39 | Sk *sm9curve.G1 40 | } 41 | 42 | //Sm9Sig contains a big number and an element in G1. 43 | type Sm9Sig struct { 44 | H *big.Int 45 | S *sm9curve.G1 46 | } 47 | 48 | //hash implements H1(Z,n) or H2(Z,n) in sm9 algorithm. 49 | func hash(z []byte, n *big.Int, h hashMode) *big.Int { 50 | //counter 51 | ct := 1 52 | 53 | hlen := 8 * int(math.Ceil(float64(5*n.BitLen()/32))) 54 | 55 | var ha []byte 56 | for i := 0; i < int(math.Ceil(float64(hlen/256))); i++ { 57 | msg := append([]byte{byte(h)}, z...) 58 | buf := make([]byte, 4) 59 | binary.BigEndian.PutUint32(buf, uint32(ct)) 60 | msg = append(msg, buf...) 61 | hai := sm3.SumSM3(msg) 62 | ct++ 63 | if float64(hlen)/256 == float64(int64(hlen/256)) && i == int(math.Ceil(float64(hlen/256)))-1 { 64 | ha = append(ha, hai[:(hlen-256*int(math.Floor(float64(hlen/256))))/32]...) 65 | } else { 66 | ha = append(ha, hai[:]...) 67 | } 68 | } 69 | 70 | bn := new(big.Int).SetBytes(ha) 71 | one := big.NewInt(1) 72 | nMinus1 := new(big.Int).Sub(n, one) 73 | bn.Mod(bn, nMinus1) 74 | bn.Add(bn, one) 75 | 76 | return bn 77 | } 78 | 79 | //generate rand numbers in [1,n-1]. 80 | func randFieldElement(rand io.Reader, n *big.Int) (k *big.Int, err error) { 81 | one := big.NewInt(1) 82 | b := make([]byte, 256/8+8) 83 | _, err = io.ReadFull(rand, b) 84 | if err != nil { 85 | return 86 | } 87 | k = new(big.Int).SetBytes(b) 88 | nMinus1 := new(big.Int).Sub(n, one) 89 | k.Mod(k, nMinus1) 90 | return 91 | } 92 | 93 | //generate master key for KGC(Key Generate Center). 94 | func MasterKeyGen(rand io.Reader) (mk *MasterKey, err error) { 95 | s, err := randFieldElement(rand, sm9curve.Order) 96 | if err != nil { 97 | return nil, errors.Errorf("gen rand num err:%s", err) 98 | } 99 | 100 | mk = new(MasterKey) 101 | mk.Msk = new(big.Int).Set(s) 102 | 103 | mk.Mpk = new(sm9curve.G2).ScalarBaseMult(s) 104 | 105 | return 106 | } 107 | 108 | //generate user's secret key. 109 | func UserKeyGen(mk *MasterKey, id []byte, hid byte) (uk *UserKey, err error) { 110 | id = append(id, hid) 111 | n := sm9curve.Order 112 | t1 := hash(id, n, H1) 113 | t1.Add(t1, mk.Msk) 114 | 115 | //if t1 = 0, we need to regenerate the master key. 116 | if t1.BitLen() == 0 || t1.Cmp(n) == 0 { 117 | return nil, errors.New("need to regen mk!") 118 | } 119 | 120 | t1.ModInverse(t1, n) 121 | 122 | //t2 = s*t1^-1 123 | t2 := new(big.Int).Mul(mk.Msk, t1) 124 | 125 | uk = new(UserKey) 126 | uk.Sk = new(sm9curve.G1).ScalarBaseMult(t2) 127 | return 128 | } 129 | 130 | //sm9 sign algorithm: 131 | //A1:compute g = e(P1,Ppub); 132 | //A2:choose random num r in [1,n-1]; 133 | //A3:compute w = g^r; 134 | //A4:compute h = H2(M||w,n); 135 | //A5:compute l = (r-h) mod n, if l = 0 goto A2; 136 | //A6:compute S = l·sk. 137 | func Sign(uk *UserKey, mpk *MasterPubKey, msg []byte) (sig *Sm9Sig, err error) { 138 | sig = new(Sm9Sig) 139 | n := sm9curve.Order 140 | g := sm9curve.Pair(sm9curve.Gen1, mpk.Mpk) 141 | 142 | regen: 143 | r, err := randFieldElement(rand.Reader, n) 144 | if err != nil { 145 | return nil, errors.Errorf("gen rand num failed:%s", err) 146 | } 147 | 148 | w := new(sm9curve.GT).ScalarMult(g, r) 149 | 150 | wBytes := w.Marshal() 151 | 152 | msg = append(msg, wBytes...) 153 | 154 | h := hash(msg, n, H2) 155 | 156 | sig.H = new(big.Int).Set(h) 157 | 158 | l := new(big.Int).Sub(r, h) 159 | l.Mod(l, n) 160 | 161 | if l.BitLen() == 0 { 162 | goto regen 163 | } 164 | 165 | sig.S = new(sm9curve.G1).ScalarMult(uk.Sk, l) 166 | 167 | return 168 | } 169 | 170 | //sm9 verify algorithm(given sig (h',S'), message M' and user's id): 171 | //B1:compute g = e(P1,Ppub); 172 | //B2:compute t = g^h'; 173 | //B3:compute h1 = H1(id||hid,n); 174 | //B4:compute P = h1·P2+Ppub; 175 | //B5:compute u = e(S',P); 176 | //B6:compute w' = u·t; 177 | //B7:compute h2 = H2(M'||w',n), check if h2 = h'. 178 | func Verify(sig *Sm9Sig, msg []byte, id []byte, hid byte, mpk *MasterPubKey) bool { 179 | n := sm9curve.Order 180 | g := sm9curve.Pair(sm9curve.Gen1, mpk.Mpk) 181 | 182 | t := new(sm9curve.GT).ScalarMult(g, sig.H) 183 | 184 | id = append(id, hid) 185 | 186 | h1 := hash(id, n, H1) 187 | 188 | P := new(sm9curve.G2).ScalarBaseMult(h1) 189 | 190 | P.Add(P, mpk.Mpk) 191 | 192 | u := sm9curve.Pair(sig.S, P) 193 | 194 | w := new(sm9curve.GT).Add(u, t) 195 | 196 | wBytes := w.Marshal() 197 | 198 | msg = append(msg, wBytes...) 199 | 200 | h2 := hash(msg, n, H2) 201 | 202 | if h2.Cmp(sig.H) != 0 { 203 | return false 204 | } 205 | 206 | return true 207 | } 208 | -------------------------------------------------------------------------------- /elliptic/sm9curve/curve.go: -------------------------------------------------------------------------------- 1 | package sm9curve 2 | 3 | import ( 4 | "math/big" 5 | ) 6 | 7 | // curvePoint implements the elliptic curve y²=x³+5. Points are kept in Jacobian 8 | // form and t=z² when valid. G₁ is the set of points of this curve on GF(p). 9 | type curvePoint struct { 10 | x, y, z, t gfP 11 | } 12 | 13 | var curveB = newGFp(5) 14 | 15 | // curveGen is the generator of G₁ (in form of montEncode). 16 | var curveGen = &curvePoint{ 17 | x: gfP{0x22e935e29860501b, 0xa946fd5e0073282c, 0xefd0cec817a649be, 0x5129787c869140b5}, 18 | y: gfP{0xee779649eb87f7c7, 0x15563cbdec30a576, 0x326353912824efbf, 0x7215717763c39828}, 19 | z: *newGFp(1), 20 | t: *newGFp(1), 21 | } 22 | 23 | func (c *curvePoint) String() string { 24 | c.MakeAffine() 25 | x, y := &gfP{}, &gfP{} 26 | montDecode(x, &c.x) 27 | montDecode(y, &c.y) 28 | return "(" + x.String() + ", " + y.String() + ")" 29 | } 30 | 31 | func (c *curvePoint) Set(a *curvePoint) { 32 | c.x.Set(&a.x) 33 | c.y.Set(&a.y) 34 | c.z.Set(&a.z) 35 | c.t.Set(&a.t) 36 | } 37 | 38 | // IsOnCurve returns true iff c is on the curve. 39 | func (c *curvePoint) IsOnCurve() bool { 40 | c.MakeAffine() 41 | if c.IsInfinity() { 42 | return true 43 | } 44 | 45 | y2, x3 := &gfP{}, &gfP{} 46 | gfpMul(y2, &c.y, &c.y) 47 | gfpMul(x3, &c.x, &c.x) 48 | gfpMul(x3, x3, &c.x) 49 | gfpAdd(x3, x3, curveB) 50 | 51 | return *y2 == *x3 52 | } 53 | 54 | func (c *curvePoint) SetInfinity() { 55 | c.x = gfP{0} 56 | c.y = *newGFp(1) 57 | c.z = gfP{0} 58 | c.t = gfP{0} 59 | } 60 | 61 | func (c *curvePoint) IsInfinity() bool { 62 | return c.z == gfP{0} 63 | } 64 | 65 | func (c *curvePoint) Add(a, b *curvePoint) { 66 | if a.IsInfinity() { 67 | c.Set(b) 68 | return 69 | } 70 | if b.IsInfinity() { 71 | c.Set(a) 72 | return 73 | } 74 | 75 | // See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/addition/add-2007-bl.op3 76 | 77 | // Normalize the points by replacing a = [x1:y1:z1] and b = [x2:y2:z2] 78 | // by [u1:s1:z1·z2] and [u2:s2:z1·z2] 79 | // where u1 = x1·z2², s1 = y1·z2³ and u1 = x2·z1², s2 = y2·z1³ 80 | z12, z22 := &gfP{}, &gfP{} 81 | gfpMul(z12, &a.z, &a.z) 82 | gfpMul(z22, &b.z, &b.z) 83 | 84 | u1, u2 := &gfP{}, &gfP{} 85 | gfpMul(u1, &a.x, z22) 86 | gfpMul(u2, &b.x, z12) 87 | 88 | t, s1 := &gfP{}, &gfP{} 89 | gfpMul(t, &b.z, z22) 90 | gfpMul(s1, &a.y, t) 91 | 92 | s2 := &gfP{} 93 | gfpMul(t, &a.z, z12) 94 | gfpMul(s2, &b.y, t) 95 | 96 | // Compute x = (2h)²(s²-u1-u2) 97 | // where s = (s2-s1)/(u2-u1) is the slope of the line through 98 | // (u1,s1) and (u2,s2). The extra factor 2h = 2(u2-u1) comes from the value of z below. 99 | // This is also: 100 | // 4(s2-s1)² - 4h²(u1+u2) = 4(s2-s1)² - 4h³ - 4h²(2u1) 101 | // = r² - j - 2v 102 | // with the notations below. 103 | h := &gfP{} 104 | gfpSub(h, u2, u1) 105 | xEqual := *h == gfP{0} 106 | 107 | gfpAdd(t, h, h) 108 | // i = 4h² 109 | i := &gfP{} 110 | gfpMul(i, t, t) 111 | // j = 4h³ 112 | j := &gfP{} 113 | gfpMul(j, h, i) 114 | 115 | gfpSub(t, s2, s1) 116 | yEqual := *t == gfP{0} 117 | if xEqual && yEqual { 118 | c.Double(a) 119 | return 120 | } 121 | r := &gfP{} 122 | gfpAdd(r, t, t) 123 | 124 | v := &gfP{} 125 | gfpMul(v, u1, i) 126 | 127 | // t4 = 4(s2-s1)² 128 | t4, t6 := &gfP{}, &gfP{} 129 | gfpMul(t4, r, r) 130 | gfpAdd(t, v, v) 131 | gfpSub(t6, t4, j) 132 | 133 | gfpSub(&c.x, t6, t) 134 | 135 | // Set y = -(2h)³(s1 + s*(x/4h²-u1)) 136 | // This is also 137 | // y = - 2·s1·j - (s2-s1)(2x - 2i·u1) = r(v-x) - 2·s1·j 138 | gfpSub(t, v, &c.x) // t7 139 | gfpMul(t4, s1, j) // t8 140 | gfpAdd(t6, t4, t4) // t9 141 | gfpMul(t4, r, t) // t10 142 | gfpSub(&c.y, t4, t6) 143 | 144 | // Set z = 2(u2-u1)·z1·z2 = 2h·z1·z2 145 | gfpAdd(t, &a.z, &b.z) // t11 146 | gfpMul(t4, t, t) // t12 147 | gfpSub(t, t4, z12) // t13 148 | gfpSub(t4, t, z22) // t14 149 | gfpMul(&c.z, t4, h) 150 | } 151 | 152 | func (c *curvePoint) Double(a *curvePoint) { 153 | // See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/doubling/dbl-2009-l.op3 154 | A, B, C := &gfP{}, &gfP{}, &gfP{} 155 | gfpMul(A, &a.x, &a.x) 156 | gfpMul(B, &a.y, &a.y) 157 | gfpMul(C, B, B) 158 | 159 | t, t2 := &gfP{}, &gfP{} 160 | gfpAdd(t, &a.x, B) 161 | gfpMul(t2, t, t) 162 | gfpSub(t, t2, A) 163 | gfpSub(t2, t, C) 164 | 165 | d, e, f := &gfP{}, &gfP{}, &gfP{} 166 | gfpAdd(d, t2, t2) 167 | gfpAdd(t, A, A) 168 | gfpAdd(e, t, A) 169 | gfpMul(f, e, e) 170 | 171 | gfpAdd(t, d, d) 172 | gfpSub(&c.x, f, t) 173 | 174 | gfpMul(&c.z, &a.y, &a.z) 175 | gfpAdd(&c.z, &c.z, &c.z) 176 | 177 | gfpAdd(t, C, C) 178 | gfpAdd(t2, t, t) 179 | gfpAdd(t, t2, t2) 180 | gfpSub(&c.y, d, &c.x) 181 | gfpMul(t2, e, &c.y) 182 | gfpSub(&c.y, t2, t) 183 | } 184 | 185 | func (c *curvePoint) Mul(a *curvePoint, scalar *big.Int) { 186 | sum, t := &curvePoint{}, &curvePoint{} 187 | sum.SetInfinity() 188 | 189 | for i := scalar.BitLen(); i >= 0; i-- { 190 | t.Double(sum) 191 | if scalar.Bit(i) != 0 { 192 | sum.Add(t, a) 193 | } else { 194 | sum.Set(t) 195 | } 196 | } 197 | 198 | c.Set(sum) 199 | } 200 | 201 | func (c *curvePoint) MakeAffine() { 202 | if c.z == *newGFp(1) { 203 | return 204 | } else if c.z == *newGFp(0) { 205 | c.x = gfP{0} 206 | c.y = *newGFp(1) 207 | c.t = gfP{0} 208 | return 209 | } 210 | 211 | zInv := &gfP{} 212 | zInv.Invert(&c.z) 213 | 214 | t, zInv2 := &gfP{}, &gfP{} 215 | gfpMul(t, &c.y, zInv) 216 | gfpMul(zInv2, zInv, zInv) 217 | 218 | gfpMul(&c.x, &c.x, zInv2) 219 | gfpMul(&c.y, t, zInv2) 220 | 221 | c.z = *newGFp(1) 222 | c.t = *newGFp(1) 223 | } 224 | 225 | func (c *curvePoint) Neg(a *curvePoint) { 226 | c.x.Set(&a.x) 227 | gfpNeg(&c.y, &a.y) 228 | c.z.Set(&a.z) 229 | c.t = gfP{0} 230 | } 231 | -------------------------------------------------------------------------------- /sm/sm2/sm2_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 cetc-30. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | package sm2 5 | 6 | import ( 7 | "bytes" 8 | "crypto/rand" 9 | "encoding/hex" 10 | "github.com/xlcetc/cryptogm/elliptic/sm2curve" 11 | "github.com/xlcetc/cryptogm/sm/sm3" 12 | "math/big" 13 | "testing" 14 | ) 15 | 16 | func TestKeyGen(t *testing.T) { 17 | priv, err := GenerateKey(rand.Reader) 18 | if err != nil { 19 | t.Errorf("error: %s", err) 20 | return 21 | } 22 | 23 | if !priv.PublicKey.Curve.IsOnCurve(priv.PublicKey.X, priv.PublicKey.Y) { 24 | t.Errorf("public key is invalid: %s", err) 25 | return 26 | } 27 | } 28 | 29 | func TestSignAndVer(t *testing.T) { 30 | msg := []byte("sm2 message") 31 | priv, err := GenerateKey(rand.Reader) 32 | if err != nil { 33 | panic("GenerateKey failed") 34 | } 35 | 36 | hfunc := sm3.New() 37 | hfunc.Write(msg) 38 | hash := hfunc.Sum(nil) 39 | 40 | r, s, err := Sign(rand.Reader, priv, hash) 41 | 42 | if err != nil { 43 | panic(err) 44 | } 45 | 46 | if !Verify(&priv.PublicKey, hash, r, s) { 47 | t.Error("signature is invalid!") 48 | return 49 | } 50 | } 51 | 52 | func TestSignAndVerWithDigest(t *testing.T) { 53 | msg := []byte("sm2 message") 54 | priv, err := GenerateKey(rand.Reader) 55 | if err != nil { 56 | t.Errorf("GenerateKey failed:%s", err) 57 | return 58 | } 59 | 60 | var m = make([]byte, 32+len(msg)) 61 | copy(m, getZ(&priv.PublicKey)) 62 | copy(m[32:], msg) 63 | digest := sm3.SumSM3(m) 64 | r, s, err := SignWithDigest(rand.Reader, priv, digest[:]) 65 | if err != nil { 66 | t.Errorf("sign with digest failed:%s", err) 67 | return 68 | } 69 | 70 | if !VerifyWithDigest(&priv.PublicKey, digest[:], r, s) { 71 | t.Error("sig is invalid!") 72 | return 73 | } 74 | } 75 | 76 | func TestSignAndVerWithAsn1(t *testing.T) { 77 | msg := []byte("sm2 message") 78 | priv, err := GenerateKey(rand.Reader) 79 | if err != nil { 80 | t.Errorf("GenerateKey failed:%s", err) 81 | return 82 | } 83 | 84 | sig, err := priv.Sign(rand.Reader, msg) 85 | if err != nil { 86 | t.Errorf("sm2 sign failed:%s", err) 87 | return 88 | } 89 | 90 | if !(&priv.PublicKey).Verify(msg, sig) { 91 | t.Error("sig is invalid!") 92 | return 93 | } 94 | } 95 | 96 | func BenchmarkSign(b *testing.B) { 97 | hashed := []byte("testing") 98 | priv, _ := GenerateKey(rand.Reader) 99 | 100 | for i := 0; i < b.N; i++ { 101 | _, _, _ = Sign(rand.Reader, priv, hashed) 102 | } 103 | } 104 | 105 | func BenchmarkVerify(b *testing.B) { 106 | priv, _ := GenerateKey(rand.Reader) 107 | 108 | origin := []byte("testing") 109 | hash := sm3.New() 110 | hash.Write(origin) 111 | hashed := hash.Sum(nil) 112 | 113 | sig, _ := priv.Sign(rand.Reader, hashed) 114 | 115 | b.ResetTimer() 116 | for i := 0; i < b.N; i++ { 117 | (&priv.PublicKey).Verify(hashed, sig) 118 | } 119 | } 120 | 121 | func BenchmarkSignWithDigest(b *testing.B) { 122 | priv, _ := GenerateKey(rand.Reader) 123 | 124 | origin := []byte("testing") 125 | hash := sm3.New() 126 | hash.Write(origin) 127 | hashed := hash.Sum(nil) 128 | b.ResetTimer() 129 | for i := 0; i < b.N; i++ { 130 | _, _, _ = SignWithDigest(rand.Reader, priv, hashed) 131 | } 132 | } 133 | 134 | func BenchmarkVerifyWithDigest(b *testing.B) { 135 | priv, _ := GenerateKey(rand.Reader) 136 | 137 | origin := []byte("testing") 138 | hash := sm3.New() 139 | hash.Write(origin) 140 | hashed := hash.Sum(nil) 141 | 142 | r, s, _ := SignWithDigest(rand.Reader, priv, hashed) 143 | 144 | b.ResetTimer() 145 | for i := 0; i < b.N; i++ { 146 | VerifyWithDigest(&priv.PublicKey, hashed, r, s) 147 | } 148 | } 149 | 150 | func BenchmarkSignWithASN1(b *testing.B) { 151 | priv, _ := GenerateKey(rand.Reader) 152 | 153 | msg := []byte("message") 154 | b.ResetTimer() 155 | for i := 0; i < b.N; i++ { 156 | _, _ = priv.Sign(rand.Reader, msg) 157 | } 158 | } 159 | 160 | func BenchmarkVerifyWithASN1(b *testing.B) { 161 | priv, _ := GenerateKey(rand.Reader) 162 | 163 | msg := []byte("message") 164 | 165 | sig, _ := priv.Sign(rand.Reader, msg) 166 | 167 | b.ResetTimer() 168 | for i := 0; i < b.N; i++ { 169 | (&priv.PublicKey).Verify(msg, sig) 170 | } 171 | } 172 | func TestEncAndDec(t *testing.T) { 173 | msg := []byte("sm2 encryption standard") 174 | 175 | sk, _ := GenerateKey(rand.Reader) 176 | pk := sk.PublicKey 177 | 178 | //test encryption 179 | cipher, err := Encrypt(rand.Reader, &pk, msg) 180 | if err != nil { 181 | t.Errorf("enc err:%s", err) 182 | return 183 | } 184 | 185 | //test decryption 186 | plain, err := Decrypt(cipher, sk) 187 | if err != nil { 188 | t.Errorf("dec err:%s", err) 189 | return 190 | } 191 | 192 | if !bytes.Equal(msg, plain) { 193 | t.Error("sm2 encryption is invalid") 194 | return 195 | } 196 | } 197 | 198 | func TestDecrypt(t *testing.T) { 199 | c, _ := hex.DecodeString("04c03f6661e748ca80880af89237981a6ec80155971d41a0f128e7edef0ba332daf4d804d0d0df33f" + 200 | "90928a8bce36d41bbd89313978ec706775a7045f58866715e511257c5b91b5f30f8cfcf55cf4b6228dbd91288e5a36a63a4b37e0a" + 201 | "dc7c758d95f6c6cabc1e1f6db87715948452070d915d02f58b8abec4e1972ae431274dfcd5e9d955db04f2eb5f48d9db15df968cf" + 202 | "ea53cfff8c00063ff204e99207b734c170230") 203 | msg, _ := hex.DecodeString("f4de77e8488e0076893b438d9d053d870abf3deeb55cd53e58e763f411c8a60b95e8e8d205c533fc9e3d5016fb7d4a1c0ae1197703edda64d69b4d0532be23c3e3239e") 204 | 205 | sk, _ := new(big.Int).SetString("14616ccf33a996453b4c7e8b03027af00d84a0fd89ceff38effac1595c68433a", 16) 206 | 207 | pkx, pky := sm2curve.P256().ScalarBaseMult(sk.Bytes()) 208 | 209 | priv := PrivateKey{PublicKey{sm2curve.P256(), pkx, pky, nil}, sk, nil} 210 | 211 | plain, err := Decrypt(c, &priv) 212 | if err != nil { 213 | t.Errorf("dec err:%s", err) 214 | return 215 | } 216 | 217 | if !bytes.Equal(msg, plain) { 218 | t.Error("decryption is invalid") 219 | return 220 | } 221 | } 222 | -------------------------------------------------------------------------------- /elliptic/sm9curve/gfp6.go: -------------------------------------------------------------------------------- 1 | package sm9curve 2 | 3 | // For details of the algorithms used, see "Multiplication and Squaring on 4 | // Pairing-Friendly Fields, Devegili et al. 5 | // http://eprint.iacr.org/2006/471.pdf. 6 | 7 | // gfP6 implements the field of size p⁶ as a cubic extension of gfP2 where τ³=ξ 8 | // and ξ=bi, b = 41217008327289123222415381552622984564801580633467584818956296086707730162366. 9 | type gfP6 struct { 10 | x, y, z gfP2 // value is xτ² + yτ + z 11 | } 12 | 13 | func (e *gfP6) String() string { 14 | return "(" + e.x.String() + ", " + e.y.String() + ", " + e.z.String() + ")" 15 | } 16 | 17 | func (e *gfP6) Set(a *gfP6) *gfP6 { 18 | e.x.Set(&a.x) 19 | e.y.Set(&a.y) 20 | e.z.Set(&a.z) 21 | return e 22 | } 23 | 24 | func (e *gfP6) SetZero() *gfP6 { 25 | e.x.SetZero() 26 | e.y.SetZero() 27 | e.z.SetZero() 28 | return e 29 | } 30 | 31 | func (e *gfP6) SetOne() *gfP6 { 32 | e.x.SetZero() 33 | e.y.SetZero() 34 | e.z.SetOne() 35 | return e 36 | } 37 | 38 | func (e *gfP6) IsZero() bool { 39 | return e.x.IsZero() && e.y.IsZero() && e.z.IsZero() 40 | } 41 | 42 | func (e *gfP6) IsOne() bool { 43 | return e.x.IsZero() && e.y.IsZero() && e.z.IsOne() 44 | } 45 | 46 | func (e *gfP6) Neg(a *gfP6) *gfP6 { 47 | e.x.Neg(&a.x) 48 | e.y.Neg(&a.y) 49 | e.z.Neg(&a.z) 50 | return e 51 | } 52 | 53 | func (e *gfP6) Frobenius(a *gfP6) *gfP6 { 54 | e.x.Conjugate(&a.x) 55 | e.y.Conjugate(&a.y) 56 | e.z.Conjugate(&a.z) 57 | 58 | e.x.MulScalar(&e.x, xiTo2PMinus2Over3) 59 | e.y.MulScalar(&e.y, xiToPMinus1Over3) 60 | return e 61 | } 62 | 63 | // FrobeniusP2 computes (xτ²+yτ+z)^(p²) = xτ^(2p²) + yτ^(p²) + z 64 | func (e *gfP6) FrobeniusP2(a *gfP6) *gfP6 { 65 | // τ^(2p²) = τ²τ^(2p²-2) = τ²ξ^((2p²-2)/3) 66 | e.x.MulScalar(&a.x, xiTo2PSquaredMinus2Over3) 67 | // τ^(p²) = ττ^(p²-1) = τξ^((p²-1)/3) 68 | e.y.MulScalar(&a.y, xiToPSquaredMinus1Over3) 69 | e.z.Set(&a.z) 70 | return e 71 | } 72 | 73 | //func (e *gfP6) FrobeniusP4(a *gfP6) *gfP6 { 74 | // e.x.MulScalar(&a.x,xiToPSquaredMinus1Over3) 75 | // e.y.MulScalar(&a.y, xiTo2PSquaredMinus2Over3) 76 | // e.z.Set(&a.z) 77 | // return e 78 | //} 79 | 80 | func (e *gfP6) Add(a, b *gfP6) *gfP6 { 81 | e.x.Add(&a.x, &b.x) 82 | e.y.Add(&a.y, &b.y) 83 | e.z.Add(&a.z, &b.z) 84 | return e 85 | } 86 | 87 | func (e *gfP6) Sub(a, b *gfP6) *gfP6 { 88 | e.x.Sub(&a.x, &b.x) 89 | e.y.Sub(&a.y, &b.y) 90 | e.z.Sub(&a.z, &b.z) 91 | return e 92 | } 93 | 94 | func (e *gfP6) Mul(a, b *gfP6) *gfP6 { 95 | // "Multiplication and Squaring on Pairing-Friendly Fields" 96 | // Section 4, Karatsuba method. 97 | // http://eprint.iacr.org/2006/471.pdf 98 | v0 := (&gfP2{}).Mul(&a.z, &b.z) 99 | v1 := (&gfP2{}).Mul(&a.y, &b.y) 100 | v2 := (&gfP2{}).Mul(&a.x, &b.x) 101 | 102 | t0 := (&gfP2{}).Add(&a.x, &a.y) 103 | t1 := (&gfP2{}).Add(&b.x, &b.y) 104 | tz := (&gfP2{}).Mul(t0, t1) 105 | tz.Sub(tz, v1).Sub(tz, v2) 106 | tz.MulXi(tz) 107 | tz.Add(tz, v0) 108 | 109 | t0.Add(&a.y, &a.z) 110 | t1.Add(&b.y, &b.z) 111 | ty := (&gfP2{}).Mul(t0, t1) 112 | t0.MulXi(v2) 113 | ty.Sub(ty, v0).Sub(ty, v1).Add(ty, t0) 114 | 115 | t0.Add(&a.x, &a.z) 116 | t1.Add(&b.x, &b.z) 117 | tx := (&gfP2{}).Mul(t0, t1) 118 | tx.Sub(tx, v0).Add(tx, v1).Sub(tx, v2) 119 | 120 | e.x.Set(tx) 121 | e.y.Set(ty) 122 | e.z.Set(tz) 123 | return e 124 | } 125 | 126 | func (e *gfP6) MulScalar(a *gfP6, b *gfP2) *gfP6 { 127 | e.x.Mul(&a.x, b) 128 | e.y.Mul(&a.y, b) 129 | e.z.Mul(&a.z, b) 130 | return e 131 | } 132 | 133 | func (e *gfP6) MulGFP(a *gfP6, b *gfP) *gfP6 { 134 | e.x.MulScalar(&a.x, b) 135 | e.y.MulScalar(&a.y, b) 136 | e.z.MulScalar(&a.z, b) 137 | return e 138 | } 139 | 140 | // MulTau computes τ·(aτ²+bτ+c) = bτ²+cτ+aξ 141 | func (e *gfP6) MulTau(a *gfP6) *gfP6 { 142 | tz := (&gfP2{}).MulXi(&a.x) 143 | ty := (&gfP2{}).Set(&a.y) 144 | 145 | e.y.Set(&a.z) 146 | e.x.Set(ty) 147 | e.z.Set(tz) 148 | return e 149 | } 150 | 151 | func (e *gfP6) Square(a *gfP6) *gfP6 { 152 | v0 := (&gfP2{}).Square(&a.z) 153 | v1 := (&gfP2{}).Square(&a.y) 154 | v2 := (&gfP2{}).Square(&a.x) 155 | 156 | c0 := (&gfP2{}).Add(&a.x, &a.y) 157 | c0.Square(c0).Sub(c0, v1).Sub(c0, v2).MulXi(c0).Add(c0, v0) 158 | 159 | c1 := (&gfP2{}).Add(&a.y, &a.z) 160 | c1.Square(c1).Sub(c1, v0).Sub(c1, v1) 161 | xiV2 := (&gfP2{}).MulXi(v2) 162 | c1.Add(c1, xiV2) 163 | 164 | c2 := (&gfP2{}).Add(&a.x, &a.z) 165 | c2.Square(c2).Sub(c2, v0).Add(c2, v1).Sub(c2, v2) 166 | 167 | e.x.Set(c2) 168 | e.y.Set(c1) 169 | e.z.Set(c0) 170 | return e 171 | } 172 | 173 | func (e *gfP6) Invert(a *gfP6) *gfP6 { 174 | // See "Implementing cryptographic pairings", M. Scott, section 3.2. 175 | // ftp://136.206.11.249/pub/crypto/pairings.pdf 176 | 177 | // Here we can give a short explanation of how it works: let j be a cubic root of 178 | // unity in GF(p²) so that 1+j+j²=0. 179 | // Then (xτ² + yτ + z)(xj²τ² + yjτ + z)(xjτ² + yj²τ + z) 180 | // = (xτ² + yτ + z)(Cτ²+Bτ+A) 181 | // = (x³ξ²+y³ξ+z³-3ξxyz) = F is an element of the base field (the norm). 182 | // 183 | // On the other hand (xj²τ² + yjτ + z)(xjτ² + yj²τ + z) 184 | // = τ²(y²-ξxz) + τ(ξx²-yz) + (z²-ξxy) 185 | // 186 | // So that's why A = (z²-ξxy), B = (ξx²-yz), C = (y²-xz) 187 | t1 := (&gfP2{}).Mul(&a.x, &a.y) 188 | t1.MulXi(t1) 189 | 190 | A := (&gfP2{}).Square(&a.z) 191 | A.Sub(A, t1) 192 | 193 | B := (&gfP2{}).Square(&a.x) 194 | B.MulXi(B) 195 | t1.Mul(&a.y, &a.z) 196 | B.Sub(B, t1) 197 | 198 | C := (&gfP2{}).Square(&a.y) 199 | t1.Mul(&a.x, &a.z) 200 | C.Sub(C, t1) 201 | 202 | F := (&gfP2{}).Mul(C, &a.y) 203 | F.MulXi(F) 204 | t1.Mul(A, &a.z) 205 | F.Add(F, t1) 206 | t1.Mul(B, &a.x).MulXi(t1) 207 | F.Add(F, t1) 208 | 209 | F.Invert(F) 210 | 211 | e.x.Mul(C, F) 212 | e.y.Mul(B, F) 213 | e.z.Mul(A, F) 214 | return e 215 | } 216 | 217 | func montEncodeGfp6(a gfP6) (b gfP6) { 218 | var b1, b2, b3, b4, b5, b6 = gfP{}, gfP{}, gfP{}, gfP{}, gfP{}, gfP{} 219 | montEncode(&b1, &a.x.x) 220 | montEncode(&b2, &a.x.y) 221 | montEncode(&b3, &a.y.x) 222 | montEncode(&b4, &a.y.y) 223 | montEncode(&b5, &a.z.x) 224 | montEncode(&b6, &a.z.y) 225 | b = gfP6{gfP2{b1, b2}, gfP2{b3, b4}, gfP2{b5, b6}} 226 | return b 227 | } 228 | 229 | func montDecodeGfp6(a gfP6) (b gfP6) { 230 | var b1, b2, b3, b4, b5, b6 = gfP{}, gfP{}, gfP{}, gfP{}, gfP{}, gfP{} 231 | montDecode(&b1, &a.x.x) 232 | montDecode(&b2, &a.x.y) 233 | montDecode(&b3, &a.y.x) 234 | montDecode(&b4, &a.y.y) 235 | montDecode(&b5, &a.z.x) 236 | montDecode(&b6, &a.z.y) 237 | b = gfP6{gfP2{b1, b2}, gfP2{b3, b4}, gfP2{b5, b6}} 238 | return b 239 | } 240 | -------------------------------------------------------------------------------- /elliptic/sm9curve/gfp12.go: -------------------------------------------------------------------------------- 1 | package sm9curve 2 | 3 | // For details of the algorithms used, see "Multiplication and Squaring on 4 | // Pairing-Friendly Fields, Devegili et al. 5 | // http://eprint.iacr.org/2006/471.pdf. 6 | 7 | import ( 8 | "math/big" 9 | ) 10 | 11 | // gfP12 implements the field of size p¹² as a quadratic extension of gfP6 12 | // where ω²=τ. 13 | type gfP12 struct { 14 | x, y gfP6 // value is xω + y 15 | } 16 | 17 | var gfP12Gen *gfP12 = &gfP12{ 18 | x: gfP6{ 19 | x: gfP2{ 20 | x: gfP{0x513dbc73240138c0, 0xabb39aec5c957a11, 0x2faa8e49d7294f9e, 0x6add5d304ff681e4}, 21 | y: gfP{0xb2952202400c1da7, 0x80b83e27e364ef9e, 0x470c9526f8a186a9, 0x2915ca5028d8c43a}, 22 | }, 23 | y: gfP2{ 24 | x: gfP{0x4218861fe3f5ae7a, 0x6b3033ab3ff1a59e, 0xa521950378e93610, 0x57f69a60583f2847}, 25 | y: gfP{0x36e4f111918e1d96, 0xa03359bb9780a652, 0x2b2bec1b0d4a4889, 0xa007d436fab467af}, 26 | }, 27 | z: gfP2{ 28 | x: gfP{0xa694d7e16d92625e, 0xec1913f15868b801, 0xaf96b4f8ed1fe80a, 0xa8479f1ac2fa5546}, 29 | y: gfP{0xa5f0fb058177d49a, 0xb1d16f82e2bc6f18, 0x3c71fa129547a729, 0x131b1915db10160d}, 30 | }, 31 | }, 32 | y: gfP6{ 33 | x: gfP2{ 34 | x: gfP{0x8ac4f31a5925bcaa, 0x5dc0eb332aa6389b, 0x6f2a25a38ccf247b, 0x65f67ec80c2071b1}, 35 | y: gfP{0x60cefaed398c3437, 0x218dc8827ef0b202, 0x4829899e34b7d867, 0x04a3b982875c7af0}, 36 | }, 37 | y: gfP2{ 38 | x: gfP{0xdf54e1763084afc2, 0x692b84e37dde076c, 0x1f3a4948122abae0, 0x581ce11e4bdc56d2}, 39 | y: gfP{0x543d49f9a76e0a4f, 0x8d247091f17aedc4, 0xe2fbea6edc133ad9, 0x8c4e46e8a40fd106}, 40 | }, 41 | z: gfP2{ 42 | x: gfP{0x075d7fecd8189dd4, 0x1406e3c8e83f2e82, 0x2f84a872d0d0cc2e, 0x7829f5625230bba8}, 43 | y: gfP{0x104d9126d962e5cd, 0x5e3472092a2ec2b0, 0xf56cf3a688b849e8, 0x84974f923ff12208}, 44 | }, 45 | }, 46 | } 47 | 48 | func (e *gfP12) String() string { 49 | return "(" + e.x.String() + "," + e.y.String() + ")" 50 | } 51 | 52 | func (e *gfP12) Set(a *gfP12) *gfP12 { 53 | e.x.Set(&a.x) 54 | e.y.Set(&a.y) 55 | return e 56 | } 57 | 58 | func (e *gfP12) SetZero() *gfP12 { 59 | e.x.SetZero() 60 | e.y.SetZero() 61 | return e 62 | } 63 | 64 | func (e *gfP12) SetOne() *gfP12 { 65 | e.x.SetZero() 66 | e.y.SetOne() 67 | return e 68 | } 69 | 70 | func (e *gfP12) IsZero() bool { 71 | return e.x.IsZero() && e.y.IsZero() 72 | } 73 | 74 | func (e *gfP12) IsOne() bool { 75 | return e.x.IsZero() && e.y.IsOne() 76 | } 77 | 78 | func (e *gfP12) Conjugate(a *gfP12) *gfP12 { 79 | e.x.Neg(&a.x) 80 | e.y.Set(&a.y) 81 | return e 82 | } 83 | 84 | func (e *gfP12) Neg(a *gfP12) *gfP12 { 85 | e.x.Neg(&a.x) 86 | e.y.Neg(&a.y) 87 | return e 88 | } 89 | 90 | // Frobenius computes (xω+y)^p = x^p ω·ξ^((p-1)/6) + y^p 91 | func (e *gfP12) Frobenius(a *gfP12) *gfP12 { 92 | e.x.Frobenius(&a.x) 93 | e.y.Frobenius(&a.y) 94 | e.x.MulGFP(&e.x, xiToPMinus1Over6) 95 | return e 96 | } 97 | 98 | // FrobeniusP2 computes (xω+y)^p² = x^p² ω·ξ^((p²-1)/6) + y^p² 99 | func (e *gfP12) FrobeniusP2(a *gfP12) *gfP12 { 100 | e.x.FrobeniusP2(&a.x) 101 | e.x.MulGFP(&e.x, xiToPSquaredMinus1Over6) 102 | e.y.FrobeniusP2(&a.y) 103 | return e 104 | } 105 | 106 | //func (e *gfP12) FrobeniusP4(a *gfP12) *gfP12 { 107 | // e.x.FrobeniusP4(&a.x) 108 | // e.x.MulGFP(&e.x, xiToPSquaredMinus1Over3) 109 | // e.y.FrobeniusP4(&a.y) 110 | // return e 111 | //} 112 | 113 | func (e *gfP12) Add(a, b *gfP12) *gfP12 { 114 | e.x.Add(&a.x, &b.x) 115 | e.y.Add(&a.y, &b.y) 116 | return e 117 | } 118 | 119 | func (e *gfP12) Sub(a, b *gfP12) *gfP12 { 120 | e.x.Sub(&a.x, &b.x) 121 | e.y.Sub(&a.y, &b.y) 122 | return e 123 | } 124 | 125 | func (e *gfP12) Mul(a, b *gfP12) *gfP12 { 126 | tx := (&gfP6{}).Mul(&a.x, &b.y) 127 | t := (&gfP6{}).Mul(&b.x, &a.y) 128 | tx.Add(tx, t) 129 | 130 | ty := (&gfP6{}).Mul(&a.y, &b.y) 131 | t.Mul(&a.x, &b.x).MulTau(t) 132 | 133 | e.x.Set(tx) 134 | e.y.Add(ty, t) 135 | return e 136 | } 137 | 138 | func (e *gfP12) MulScalar(a *gfP12, b *gfP6) *gfP12 { 139 | e.x.Mul(&e.x, b) 140 | e.y.Mul(&e.y, b) 141 | return e 142 | } 143 | 144 | func (c *gfP12) Exp(a *gfP12, power *big.Int) *gfP12 { 145 | sum := (&gfP12{}).SetOne() 146 | t := &gfP12{} 147 | 148 | for i := power.BitLen() - 1; i >= 0; i-- { 149 | t.Square(sum) 150 | if power.Bit(i) != 0 { 151 | sum.Mul(t, a) 152 | } else { 153 | sum.Set(t) 154 | } 155 | } 156 | 157 | c.Set(sum) 158 | return c 159 | } 160 | 161 | func (e *gfP12) Square(a *gfP12) *gfP12 { 162 | // Complex squaring algorithm 163 | v0 := (&gfP6{}).Mul(&a.x, &a.y) 164 | 165 | t := (&gfP6{}).MulTau(&a.x) 166 | t.Add(&a.y, t) 167 | ty := (&gfP6{}).Add(&a.x, &a.y) 168 | ty.Mul(ty, t) 169 | ty.Sub(ty, v0) 170 | t.MulTau(v0) 171 | ty.Sub(ty, t) 172 | 173 | tx := new(gfP6).Add(v0, v0) 174 | e.x.Set(tx) 175 | e.y.Set(ty) 176 | return e 177 | } 178 | 179 | func (e *gfP12) Square1(a *gfP12) *gfP12 { 180 | tmp1 := new(gfP6).Mul(&a.x, &a.y) 181 | tmp2 := new(gfP6).Add(&a.x, &a.y) 182 | 183 | tmp3 := new(gfP6).MulTau(&a.x) 184 | ty := new(gfP6).Add(tmp3, &a.y) 185 | ty.Mul(ty, tmp2) 186 | ty.Sub(ty, tmp1) 187 | 188 | tmp2.MulTau(tmp1) 189 | ty.Sub(ty, tmp2) 190 | 191 | tx := new(gfP6).Add(tmp1, tmp1) 192 | 193 | e.x.Set(tx) 194 | e.y.Set(ty) 195 | return e 196 | } 197 | 198 | func (e *gfP12) Invert(a *gfP12) *gfP12 { 199 | // See "Implementing cryptographic pairings", M. Scott, section 3.2. 200 | // ftp://136.206.11.249/pub/crypto/pairings.pdf 201 | t1, t2 := &gfP6{}, &gfP6{} 202 | 203 | t1.Square(&a.x) 204 | t2.Square(&a.y) 205 | t1.MulTau(t1).Sub(t2, t1) 206 | t2.Invert(t1) 207 | 208 | e.x.Neg(&a.x) 209 | e.y.Set(&a.y) 210 | e.MulScalar(e, t2) 211 | return e 212 | } 213 | 214 | func montEncodeGfp12(a gfP12) (b gfP12) { 215 | var b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12 = gfP{}, gfP{}, gfP{}, gfP{}, gfP{}, gfP{}, gfP{}, gfP{}, gfP{}, gfP{}, gfP{}, gfP{} 216 | montEncode(&b1, &a.x.x.x) 217 | montEncode(&b2, &a.x.x.y) 218 | montEncode(&b3, &a.x.y.x) 219 | montEncode(&b4, &a.x.y.y) 220 | montEncode(&b5, &a.x.z.x) 221 | montEncode(&b6, &a.x.z.y) 222 | montEncode(&b7, &a.y.x.x) 223 | montEncode(&b8, &a.y.x.y) 224 | montEncode(&b9, &a.y.y.x) 225 | montEncode(&b10, &a.y.y.y) 226 | montEncode(&b11, &a.y.z.x) 227 | montEncode(&b12, &a.y.z.y) 228 | b = gfP12{gfP6{gfP2{b1, b2}, gfP2{b3, b4}, gfP2{b5, b6}}, 229 | gfP6{gfP2{b7, b8}, gfP2{b9, b10}, gfP2{b11, b12}}} 230 | return b 231 | } 232 | 233 | func montDecodeGfp12(a gfP12) (b gfP12) { 234 | var b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12 = gfP{}, gfP{}, gfP{}, gfP{}, gfP{}, gfP{}, gfP{}, gfP{}, gfP{}, gfP{}, gfP{}, gfP{} 235 | montDecode(&b1, &a.x.x.x) 236 | montDecode(&b2, &a.x.x.y) 237 | montDecode(&b3, &a.x.y.x) 238 | montDecode(&b4, &a.x.y.y) 239 | montDecode(&b5, &a.x.z.x) 240 | montDecode(&b6, &a.x.z.y) 241 | montDecode(&b7, &a.y.x.x) 242 | montDecode(&b8, &a.y.x.y) 243 | montDecode(&b9, &a.y.y.x) 244 | montDecode(&b10, &a.y.y.y) 245 | montDecode(&b11, &a.y.z.x) 246 | montDecode(&b12, &a.y.z.y) 247 | b = gfP12{gfP6{gfP2{b1, b2}, gfP2{b3, b4}, gfP2{b5, b6}}, 248 | gfP6{gfP2{b7, b8}, gfP2{b9, b10}, gfP2{b11, b12}}} 249 | return b 250 | } 251 | -------------------------------------------------------------------------------- /sm/sm4/sm4.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 cetc-30. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package sm4 implements the sm4 algorithms 6 | 7 | package sm4 8 | 9 | import ( 10 | "bytes" 11 | "crypto/cipher" 12 | "errors" 13 | "strconv" 14 | ) 15 | 16 | type KeySizeError int 17 | 18 | // Cipher is an instance of SM4 encryption. 19 | type Sm4Cipher struct { 20 | rk []uint32 21 | } 22 | 23 | //sbox,(b0,b1,b2,b3)=τ(A)=(sBox(a0),sBox(a1),sBox(a2),sBox(a3)) 24 | func scSbox(in byte) byte { 25 | var x, y int 26 | x = (int)(in >> 4 & 0x0f) 27 | y = (int)(in & 0x0f) 28 | return sbox[x][y] 29 | } 30 | 31 | //linear transformation L,C=L(B)=B^(B<<<2)^(B<<<10)^(B<<<18)^(B<<<24) 32 | func l(in uint32) uint32 { 33 | return in ^ leftRotate(in, 2) ^ leftRotate(in, 10) ^ leftRotate(in, 18) ^ leftRotate(in, 24) 34 | } 35 | 36 | //linear transformation L',C=L'(B)=B^(B<<<13)^(B<<<23) 37 | func key_l(in uint32) uint32 { 38 | return in ^ leftRotate(in, 13) ^ leftRotate(in, 23) 39 | } 40 | 41 | func rightRotate(x uint32, r int) uint32 { 42 | var rr uint32 = uint32(r) 43 | return ((x >> rr) | (x << (32 - rr))) & 0xffffffff 44 | } 45 | 46 | func leftRotate(x uint32, r int) uint32 { 47 | var rr uint32 = uint32(r) 48 | return ((x << rr) | (x >> (32 - rr))) & 0xffffffff 49 | } 50 | 51 | //linear transformation τ() 52 | func tt(in uint32) uint32 { 53 | var tmp [4]byte 54 | var re uint32 55 | tmp[0] = byte(in>>24) & 0xff 56 | tmp[1] = byte(in>>16) & 0xff 57 | tmp[2] = byte(in>>8) & 0xff 58 | tmp[3] = byte(in) & 0xff 59 | re = uint32(scSbox(tmp[3])) | 60 | (uint32(scSbox(tmp[2])) << 8) | 61 | (uint32(scSbox(tmp[1])) << 16) | 62 | (uint32(scSbox(tmp[0])) << 24) 63 | return re 64 | } 65 | 66 | //T 67 | func t3(in uint32) uint32 { 68 | return l(tt(in)) 69 | } 70 | 71 | //T' 72 | func key_t(in uint32) uint32 { 73 | return key_l(tt(in)) 74 | } 75 | 76 | //key expansion 77 | func keyExp(key [4]uint32) []uint32 { 78 | var k [36]uint32 79 | var rk [32]uint32 80 | for i := 0; i < 4; i++ { 81 | k[i] = uint32(key[i]) ^ fk[i] 82 | } 83 | for i := 0; i < 32; i++ { 84 | k[i+4] = k[i] ^ key_t(k[i+1]^k[i+2]^k[i+3]^ck[i]) 85 | rk[i] = k[i+4] 86 | } 87 | return rk[:] 88 | } 89 | 90 | //crypt block,F(X0,X1,X2,X3)=X0^T(X1^X2^X3^rk) 91 | func cryptBlock(rk []uint32, dst, src []byte, mode cryptMode) { 92 | var x uint32 93 | b := make([]uint32, 4) 94 | r := make([]byte, 16) 95 | //byte to uint32 96 | for i := 0; i < 4; i++ { 97 | b[i] = (uint32(src[i*4]) << 24) | (uint32(src[i*4+1]) << 16) | 98 | (uint32(src[i*4+2]) << 8) | (uint32(src[i*4+3])) 99 | } 100 | 101 | if mode == ENC { 102 | for i := 0; i < 8; i++ { 103 | x = b[1] ^ b[2] ^ b[3] ^ rk[4*i] 104 | b[0] = b[0] ^ sbox0[x&0xff] ^ sbox1[(x>>8)&0xff] ^ sbox2[(x>>16)&0xff] ^ sbox3[(x>>24)&0xff] 105 | x = b[0] ^ b[2] ^ b[3] ^ rk[4*i+1] 106 | b[1] = b[1] ^ sbox0[x&0xff] ^ sbox1[(x>>8)&0xff] ^ sbox2[(x>>16)&0xff] ^ sbox3[(x>>24)&0xff] 107 | x = b[0] ^ b[1] ^ b[3] ^ rk[4*i+2] 108 | b[2] = b[2] ^ sbox0[x&0xff] ^ sbox1[(x>>8)&0xff] ^ sbox2[(x>>16)&0xff] ^ sbox3[(x>>24)&0xff] 109 | x = b[1] ^ b[2] ^ b[0] ^ rk[4*i+3] 110 | b[3] = b[3] ^ sbox0[x&0xff] ^ sbox1[(x>>8)&0xff] ^ sbox2[(x>>16)&0xff] ^ sbox3[(x>>24)&0xff] 111 | } 112 | } else { 113 | for i := 0; i < 8; i++ { 114 | x = b[1] ^ b[2] ^ b[3] ^ rk[31-4*i] 115 | b[0] = b[0] ^ sbox0[x&0xff] ^ sbox1[(x>>8)&0xff] ^ sbox2[(x>>16)&0xff] ^ sbox3[(x>>24)&0xff] 116 | x = b[0] ^ b[2] ^ b[3] ^ rk[31-4*i-1] 117 | b[1] = b[1] ^ sbox0[x&0xff] ^ sbox1[(x>>8)&0xff] ^ sbox2[(x>>16)&0xff] ^ sbox3[(x>>24)&0xff] 118 | x = b[0] ^ b[1] ^ b[3] ^ rk[31-4*i-2] 119 | b[2] = b[2] ^ sbox0[x&0xff] ^ sbox1[(x>>8)&0xff] ^ sbox2[(x>>16)&0xff] ^ sbox3[(x>>24)&0xff] 120 | x = b[1] ^ b[2] ^ b[0] ^ rk[31-4*i-3] 121 | b[3] = b[3] ^ sbox0[x&0xff] ^ sbox1[(x>>8)&0xff] ^ sbox2[(x>>16)&0xff] ^ sbox3[(x>>24)&0xff] 122 | } 123 | } 124 | b[0], b[1], b[2], b[3] = b[3], b[2], b[1], b[0] 125 | 126 | //uint32 to byte 127 | for i := 0; i < 4; i++ { 128 | r[i*4] = uint8(b[i] >> 24) 129 | r[i*4+1] = uint8(b[i] >> 16) 130 | r[i*4+2] = uint8(b[i] >> 8) 131 | r[i*4+3] = uint8(b[i]) 132 | } 133 | copy(dst, r) 134 | } 135 | 136 | func (k KeySizeError) Error() string { 137 | return "SM4: invalid key size " + strconv.Itoa(int(k)) 138 | } 139 | 140 | func NewCipher(key []byte) (cipher.Block, error) { 141 | if len(key) != BlockSize { 142 | return nil, KeySizeError(len(key)) 143 | } 144 | c := new(Sm4Cipher) 145 | var k [4]uint32 146 | for i := 0; i < 4; i++ { 147 | k[i] = (uint32(key[i*4]) << 24) | (uint32(key[i*4+1]) << 16) | 148 | (uint32(key[i*4+2]) << 8) | (uint32(key[i*4+3])) 149 | } 150 | c.rk = keyExp(k) 151 | return c, nil 152 | } 153 | 154 | func (c *Sm4Cipher) BlockSize() int { 155 | return BlockSize 156 | } 157 | 158 | func (c *Sm4Cipher) Encrypt(dst, src []byte) { 159 | cryptBlock(c.rk, dst, src, ENC) 160 | } 161 | 162 | func (c *Sm4Cipher) Decrypt(dst, src []byte) { 163 | cryptBlock(c.rk, dst, src, DEC) 164 | } 165 | 166 | func pkcs7Padding(src []byte) []byte { 167 | padding := BlockSize - len(src)%BlockSize 168 | padtext := bytes.Repeat([]byte{byte(padding)}, padding) 169 | return append(src, padtext...) 170 | } 171 | 172 | func pkcs7UnPadding(src []byte) ([]byte, error) { 173 | length := len(src) 174 | unpadding := int(src[length-1]) 175 | 176 | if unpadding > BlockSize || unpadding == 0 { 177 | return nil, errors.New("Invalid pkcs7 padding (unpadding > BlockSize || unpadding == 0)") 178 | } 179 | 180 | pad := src[len(src)-unpadding:] 181 | for i := 0; i < unpadding; i++ { 182 | if pad[i] != byte(unpadding) { 183 | return nil, errors.New("Invalid pkcs7 padding (pad[i] != unpadding)") 184 | } 185 | } 186 | 187 | return src[:(length - unpadding)], nil 188 | } 189 | 190 | //sm4 ecb mode 191 | func Sm4Ecb(key []byte, in []byte, mode cryptMode) (out []byte, err error) { 192 | if len(key) != BlockSize { 193 | return nil, KeySizeError(len(key)) 194 | } 195 | var inData []byte 196 | if mode == ENC { 197 | inData = pkcs7Padding(in) 198 | } else { 199 | inData = in 200 | } 201 | out = make([]byte, len(inData)) 202 | c, err := NewCipher(key) 203 | if err != nil { 204 | panic(err) 205 | } 206 | if mode == ENC { 207 | for i := 0; i < len(inData)/16; i++ { 208 | in_tmp := inData[i*16 : i*16+16] 209 | out_tmp := make([]byte, 16) 210 | c.Encrypt(out_tmp, in_tmp) 211 | copy(out[i*16:i*16+16], out_tmp) 212 | } 213 | } else { 214 | for i := 0; i < len(inData)/16; i++ { 215 | in_tmp := inData[i*16 : i*16+16] 216 | out_tmp := make([]byte, 16) 217 | c.Decrypt(out_tmp, in_tmp) 218 | copy(out[i*16:i*16+16], out_tmp) 219 | } 220 | out, _ = pkcs7UnPadding(out) 221 | } 222 | 223 | return out, nil 224 | } 225 | 226 | func xor(in, iv []byte) (out []byte) { 227 | if len(in) != len(iv) { 228 | return nil 229 | } 230 | 231 | out = make([]byte, len(in)) 232 | for i := 0; i < len(in); i++ { 233 | out[i] = in[i] ^ iv[i] 234 | } 235 | return 236 | } 237 | 238 | //sm4 cbc mode 239 | func Sm4Cbc(key []byte, in []byte, mode cryptMode) (out []byte, err error) { 240 | if len(key) != BlockSize { 241 | return nil, KeySizeError(len(key)) 242 | } 243 | var inData []byte 244 | if mode == ENC { 245 | inData = pkcs7Padding(in) 246 | } else { 247 | inData = in 248 | } 249 | 250 | iv := make([]byte, BlockSize) 251 | 252 | out = make([]byte, len(inData)) 253 | c, err := NewCipher(key) 254 | if err != nil { 255 | panic(err) 256 | } 257 | if mode == ENC { 258 | for i := 0; i < len(inData)/16; i++ { 259 | in_tmp := xor(inData[i*16:i*16+16], iv) 260 | out_tmp := make([]byte, 16) 261 | c.Encrypt(out_tmp, in_tmp) 262 | copy(out[i*16:i*16+16], out_tmp) 263 | iv = out_tmp 264 | } 265 | } else { 266 | for i := 0; i < len(inData)/16; i++ { 267 | in_tmp := inData[i*16 : i*16+16] 268 | out_tmp := make([]byte, 16) 269 | c.Decrypt(out_tmp, in_tmp) 270 | out_tmp = xor(out_tmp, iv) 271 | copy(out[i*16:i*16+16], out_tmp) 272 | iv = in_tmp 273 | } 274 | out, _ = pkcs7UnPadding(out) 275 | } 276 | 277 | return out, nil 278 | } 279 | -------------------------------------------------------------------------------- /elliptic/sm9curve/optate.go: -------------------------------------------------------------------------------- 1 | package sm9curve 2 | 3 | func lineFunctionAdd(r, P *twistPoint, Q *curvePoint, R2 *gfP2) (a, b, c *gfP2, rOut *twistPoint) { 4 | // See the mixed addition algorithm from "Faster Computation of the 5 | // Tate Pairing", http://arxiv.org/pdf/0904.0854v3.pdf 6 | B := (&gfP2{}).Mul(&P.x, &r.t) 7 | 8 | D := (&gfP2{}).Add(&P.y, &r.z) 9 | D.Square(D).Sub(D, R2).Sub(D, &r.t).Mul(D, &r.t) 10 | 11 | H := (&gfP2{}).Sub(B, &r.x) 12 | I := (&gfP2{}).Square(H) 13 | 14 | E := (&gfP2{}).Add(I, I) 15 | E.Add(E, E) 16 | 17 | J := (&gfP2{}).Mul(H, E) 18 | 19 | L1 := (&gfP2{}).Sub(D, &r.y) 20 | L1.Sub(L1, &r.y) 21 | 22 | V := (&gfP2{}).Mul(&r.x, E) 23 | 24 | rOut = &twistPoint{} 25 | rOut.x.Square(L1).Sub(&rOut.x, J).Sub(&rOut.x, V).Sub(&rOut.x, V) 26 | 27 | rOut.z.Add(&r.z, H).Square(&rOut.z).Sub(&rOut.z, &r.t).Sub(&rOut.z, I) 28 | 29 | t := (&gfP2{}).Sub(V, &rOut.x) 30 | t.Mul(t, L1) 31 | t2 := (&gfP2{}).Mul(&r.y, J) 32 | t2.Add(t2, t2) 33 | rOut.y.Sub(t, t2) 34 | 35 | rOut.t.Square(&rOut.z) 36 | 37 | t.Add(&P.y, &rOut.z).Square(t).Sub(t, R2).Sub(t, &rOut.t) 38 | 39 | t2.Mul(L1, &P.x) 40 | t2.Add(t2, t2) 41 | a = (&gfP2{}).Sub(t2, t) 42 | 43 | c = (&gfP2{}).MulScalar(&rOut.z, &Q.y) 44 | c.Add(c, c) 45 | 46 | b = (&gfP2{}).Neg(L1) 47 | b.MulScalar(b, &Q.x).Add(b, b) 48 | 49 | return 50 | } 51 | 52 | func lineFunctionDouble(r *twistPoint, Q *curvePoint) (a, b, c *gfP2, rOut *twistPoint) { 53 | // See the doubling algorithm for a=0 from "Faster Computation of the 54 | // Tate Pairing", http://arxiv.org/pdf/0904.0854v3.pdf 55 | A := (&gfP2{}).Square(&r.x) 56 | B := (&gfP2{}).Square(&r.y) 57 | C := (&gfP2{}).Square(B) 58 | 59 | D := (&gfP2{}).Add(&r.x, B) 60 | D.Square(D).Sub(D, A).Sub(D, C).Add(D, D) 61 | 62 | E := (&gfP2{}).Add(A, A) 63 | E.Add(E, A) 64 | 65 | G := (&gfP2{}).Square(E) 66 | 67 | rOut = &twistPoint{} 68 | rOut.x.Sub(G, D).Sub(&rOut.x, D) 69 | 70 | rOut.z.Add(&r.y, &r.z).Square(&rOut.z).Sub(&rOut.z, B).Sub(&rOut.z, &r.t) 71 | 72 | rOut.y.Sub(D, &rOut.x).Mul(&rOut.y, E) 73 | t := (&gfP2{}).Add(C, C) 74 | t.Add(t, t).Add(t, t) 75 | rOut.y.Sub(&rOut.y, t) 76 | 77 | rOut.t.Square(&rOut.z) 78 | 79 | t.Mul(E, &r.t).Add(t, t) 80 | b = (&gfP2{}).Neg(t) 81 | b.MulScalar(b, &Q.x) 82 | 83 | a = (&gfP2{}).Add(&r.x, E) 84 | a.Square(a).Sub(a, A).Sub(a, G) 85 | t.Add(B, B).Add(t, t) 86 | a.Sub(a, t) 87 | 88 | c = (&gfP2{}).Mul(&rOut.z, &r.t) 89 | c.Add(c, c).MulScalar(c, &Q.y) 90 | 91 | return 92 | } 93 | 94 | func mulLine(ret *gfP12, a, b, c *gfP2) { 95 | a2 := &gfP6{} 96 | a2.y.Set(a) 97 | a2.z.Set(b) 98 | a2.Mul(a2, &ret.x) 99 | t3 := (&gfP6{}).MulScalar(&ret.y, c) 100 | 101 | t := (&gfP2{}).Add(b, c) 102 | t2 := &gfP6{} 103 | t2.y.Set(a) 104 | t2.z.Set(t) 105 | ret.x.Add(&ret.x, &ret.y) 106 | 107 | ret.y.Set(t3) 108 | 109 | ret.x.Mul(&ret.x, t2).Sub(&ret.x, a2).Sub(&ret.x, &ret.y) 110 | a2.MulTau(a2) 111 | ret.y.Add(&ret.y, a2) 112 | } 113 | 114 | func mulLine2(ret *gfP12, a, b, c *gfP2) { 115 | a2 := &gfP12{} 116 | zero := &gfP2{} 117 | zero.SetZero() 118 | 119 | a2.x.x = *zero 120 | a2.x.y = *a 121 | a2.x.z = *b 122 | a2.y.x = *zero 123 | a2.y.y = *zero 124 | a2.y.z = *c 125 | 126 | ret.Mul(ret, a2) 127 | } 128 | 129 | // sixuPlus2NAF is 6u+2 in non-adjacent form. 130 | var sixuPlus2NAF = []int8{0, -1, 0, 0, 0, 0, 1, 0, 1, 0, 0, -1, 0, -1, 0, 0, 0, -1, 0, -1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1} 131 | 132 | // miller implements the Miller loop for calculating the Optimal Ate pairing. 133 | // See algorithm 1 from http://cryptojedi.org/papers/dclxvi-20100714.pdf 134 | func miller(Q *twistPoint, P *curvePoint) *gfP12 { 135 | ret := (&gfP12{}).SetOne() 136 | 137 | aAffine := &twistPoint{} 138 | aAffine.Set(Q) 139 | aAffine.MakeAffine() 140 | 141 | bAffine := &curvePoint{} 142 | bAffine.Set(P) 143 | bAffine.MakeAffine() 144 | 145 | minusA := &twistPoint{} 146 | minusA.Neg(aAffine) 147 | 148 | r := &twistPoint{} 149 | r.Set(aAffine) 150 | 151 | R2 := (&gfP2{}).Square(&aAffine.y) 152 | 153 | for i := len(sixuPlus2NAF) - 1; i > 0; i-- { 154 | a, b, c, newR := lineFunctionDouble(r, bAffine) 155 | if i != len(sixuPlus2NAF)-1 { 156 | ret.Square(ret) 157 | } 158 | 159 | mulLine(ret, a, b, c) 160 | r = newR 161 | 162 | switch sixuPlus2NAF[i-1] { 163 | case 1: 164 | a, b, c, newR = lineFunctionAdd(r, aAffine, bAffine, R2) 165 | case -1: 166 | a, b, c, newR = lineFunctionAdd(r, minusA, bAffine, R2) 167 | default: 168 | continue 169 | } 170 | 171 | mulLine(ret, a, b, c) 172 | r = newR 173 | 174 | } 175 | 176 | // In order to calculate Q1 we have to convert q from the sextic twist 177 | // to the full GF(p^12) group, apply the Frobenius there, and convert 178 | // back. 179 | // 180 | // The twist isomorphism is (x', y') -> (xω², yω³). If we consider just 181 | // x for a moment, then after applying the Frobenius, we have x̄ω^(2p) 182 | // where x̄ is the conjugate of x. If we are going to apply the inverse 183 | // isomorphism we need a value with a single coefficient of ω² so we 184 | // rewrite this as x̄ω^(2p-2)ω². ξ⁶ = ω and, due to the construction of 185 | // p, 2p-2 is a multiple of six. Therefore we can rewrite as 186 | // x̄ξ^((p-1)/3)ω² and applying the inverse isomorphism eliminates the 187 | // ω². 188 | // 189 | // A similar argument can be made for the y value. 190 | 191 | q1 := &twistPoint{} 192 | q1.x.Conjugate(&aAffine.x).MulScalar(&q1.x, xiToPMinus1Over3) 193 | q1.y.Conjugate(&aAffine.y).MulScalar(&q1.y, xiToPMinus1Over2) 194 | q1.z.SetOne() 195 | q1.t.SetOne() 196 | 197 | // For Q2 we are applying the p² Frobenius. The two conjugations cancel 198 | // out and we are left only with the factors from the isomorphism. In 199 | // the case of x, we end up with a pure number which is why 200 | // xiToPSquaredMinus1Over3 is ∈ GF(p). With y we get a factor of -1. We 201 | // ignore this to end up with -Q2. 202 | 203 | minusQ2 := &twistPoint{} 204 | minusQ2.x.MulScalar(&aAffine.x, xiToPSquaredMinus1Over3) 205 | minusQ2.y.Set(&aAffine.y) 206 | minusQ2.z.SetOne() 207 | minusQ2.t.SetOne() 208 | 209 | R2.Square(&q1.y) 210 | a, b, c, newR := lineFunctionAdd(r, q1, bAffine, R2) 211 | mulLine(ret, a, b, c) 212 | r = newR 213 | 214 | R2.Square(&minusQ2.y) 215 | a, b, c, newR = lineFunctionAdd(r, minusQ2, bAffine, R2) 216 | mulLine(ret, a, b, c) 217 | r = newR 218 | 219 | return ret 220 | } 221 | 222 | // finalExponentiation computes the (p¹²-1)/Order-th power of an element of 223 | // GF(p¹²) to obtain an element of GT (steps 13-15 of algorithm 1 from 224 | // http://cryptojedi.org/papers/dclxvi-20100714.pdf) 225 | func finalExponentiation(in *gfP12) *gfP12 { 226 | t1 := &gfP12{} 227 | 228 | // This is the p^6-Frobenius 229 | t1.x.Neg(&in.x) 230 | t1.y.Set(&in.y) 231 | 232 | inv := &gfP12{} 233 | inv.Invert(in) 234 | t1.Mul(t1, inv) 235 | 236 | //p^2+1 237 | t2 := (&gfP12{}).FrobeniusP2(t1) 238 | t1.Mul(t1, t2) 239 | 240 | fp := (&gfP12{}).Frobenius(t1) 241 | fp2 := (&gfP12{}).FrobeniusP2(t1) 242 | fp3 := (&gfP12{}).Frobenius(fp2) 243 | 244 | fu := (&gfP12{}).Exp(t1, u) 245 | fu2 := (&gfP12{}).Exp(fu, u) 246 | fu3 := (&gfP12{}).Exp(fu2, u) 247 | 248 | y3 := (&gfP12{}).Frobenius(fu) 249 | fu2p := (&gfP12{}).Frobenius(fu2) 250 | fu3p := (&gfP12{}).Frobenius(fu3) 251 | y2 := (&gfP12{}).FrobeniusP2(fu2) 252 | 253 | y0 := &gfP12{} 254 | y0.Mul(fp, fp2).Mul(y0, fp3) 255 | 256 | y1 := (&gfP12{}).Conjugate(t1) 257 | y5 := (&gfP12{}).Conjugate(fu2) 258 | y3.Conjugate(y3) 259 | y4 := (&gfP12{}).Mul(fu, fu2p) 260 | y4.Conjugate(y4) 261 | 262 | y6 := (&gfP12{}).Mul(fu3, fu3p) 263 | y6.Conjugate(y6) 264 | 265 | t0 := (&gfP12{}).Square(y6) 266 | t0.Mul(t0, y4).Mul(t0, y5) 267 | t1.Mul(y3, y5).Mul(t1, t0) 268 | t0.Mul(t0, y2) 269 | t1.Square(t1).Mul(t1, t0).Square(t1) 270 | t0.Mul(t1, y1) 271 | t1.Mul(t1, y0) 272 | t0.Square(t0).Mul(t0, t1) 273 | 274 | return t0 275 | } 276 | 277 | ////steps 13-15 of algorithm 1 from 278 | ////"Implementing cryptographic pairings over BN curves". 279 | //NOT CORRECT!! 280 | //func finalExponentiation2(in *gfP12) *gfP12 { 281 | // t1 := &gfP12{} 282 | // 283 | // // This is the p^6-Frobenius 284 | // t1.x.Neg(&in.x) 285 | // t1.y.Set(&in.y) 286 | // 287 | // inv := &gfP12{} 288 | // inv.Invert(in) 289 | // t1.Mul(t1, inv) 290 | // 291 | // //p^2+1 292 | // t2 := (&gfP12{}).FrobeniusP2(t1) 293 | // t1.Mul(t1, t2) 294 | // 295 | // //(p^4-p^2+1)/n 296 | // six := big.NewInt(6) 297 | // five := big.NewInt(5) 298 | // one := big.NewInt(1) 299 | // nine := big.NewInt(9) 300 | // four := big.NewInt(4) 301 | // 302 | // sixxMinusFive := new(big.Int).Mul(six,u) 303 | // sixxMinusFive.Sub(sixxMinusFive,five) 304 | // 305 | // a := (&gfP12{}).Exp(t1,sixxMinusFive) 306 | // b := (&gfP12{}).Frobenius(a) 307 | // b.Mul(b,a) 308 | // 309 | // fp := (&gfP12{}).Frobenius(t1) 310 | // fpsqr := (&gfP12{}).Square(fp) 311 | // fp2 := (&gfP12{}).FrobeniusP2(t1) 312 | // fp3 := (&gfP12{}).Frobenius(fp2) 313 | // 314 | // t0 := (&gfP12{}).Mul(b,fpsqr) 315 | // t0.Mul(t0,fp2) 316 | // 317 | // sixxSquarePlusOne := new(big.Int).Mul(u,u) 318 | // sixxSquarePlusOne.Mul(six,sixxSquarePlusOne) 319 | // sixxSquarePlusOne.Add(sixxSquarePlusOne,one) 320 | // 321 | // t0.Exp(t0,sixxSquarePlusOne) 322 | // 323 | // t0.Mul(t0,fp3).Mul(t0,b).Mul(t0,a) 324 | // 325 | // tmp1 := (&gfP12{}).Mul(t1,fp) 326 | // tmp1.Exp(tmp1,nine) 327 | // temp2 := (&gfP12{}).Exp(t1,four) 328 | // t0.Mul(t0,tmp1).Mul(t0,temp2) 329 | // 330 | // return t0 331 | //} 332 | 333 | func optimalAte(a *twistPoint, b *curvePoint) *gfP12 { 334 | e := miller(a, b) 335 | ret := finalExponentiation(e) 336 | 337 | if a.IsInfinity() || b.IsInfinity() { 338 | ret.SetOne() 339 | } 340 | return ret 341 | } 342 | -------------------------------------------------------------------------------- /elliptic/sm9curve/bn256_test.go: -------------------------------------------------------------------------------- 1 | package sm9curve 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "bytes" 8 | "crypto/rand" 9 | ) 10 | 11 | func TestG1(t *testing.T) { 12 | k, Ga, err := RandomG1(rand.Reader) 13 | if err != nil { 14 | t.Fatal(err) 15 | } 16 | ma := Ga.Marshal() 17 | 18 | Gb := new(G1).ScalarBaseMult(k) 19 | 20 | mb := Gb.Marshal() 21 | 22 | if !bytes.Equal(ma, mb) { 23 | t.Fatal("bytes are different") 24 | } 25 | } 26 | 27 | func TestG1Marshal(t *testing.T) { 28 | _, Ga, err := RandomG1(rand.Reader) 29 | if err != nil { 30 | t.Fatal(err) 31 | } 32 | ma := Ga.Marshal() 33 | 34 | Gb := new(G1) 35 | _, err = Gb.Unmarshal(ma) 36 | if err != nil { 37 | t.Fatal(err) 38 | } 39 | mb := Gb.Marshal() 40 | 41 | if !bytes.Equal(ma, mb) { 42 | t.Fatal("bytes are different") 43 | } 44 | } 45 | 46 | func TestG2(t *testing.T) { 47 | k, Ga, err := RandomG2(rand.Reader) 48 | if err != nil { 49 | t.Fatal(err) 50 | } 51 | ma := Ga.Marshal() 52 | 53 | Gb := new(G2).ScalarBaseMult(k) 54 | mb := Gb.Marshal() 55 | 56 | if !bytes.Equal(ma, mb) { 57 | t.Fatal("bytes are different") 58 | } 59 | } 60 | 61 | func TestG2Marshal(t *testing.T) { 62 | _, Ga, err := RandomG2(rand.Reader) 63 | if err != nil { 64 | t.Fatal(err) 65 | } 66 | ma := Ga.Marshal() 67 | 68 | Gb := new(G2) 69 | _, err = Gb.Unmarshal(ma) 70 | if err != nil { 71 | t.Fatal(err) 72 | } 73 | mb := Gb.Marshal() 74 | 75 | if !bytes.Equal(ma, mb) { 76 | t.Fatal("bytes are different") 77 | } 78 | } 79 | 80 | func TestGT(t *testing.T) { 81 | k, Ga, err := RandomGT(rand.Reader) 82 | if err != nil { 83 | t.Fatal(err) 84 | } 85 | ma := Ga.Marshal() 86 | 87 | Gb := >{gfP12Gen} 88 | Gb.ScalarMult(Gb, k) 89 | mb := Gb.Marshal() 90 | 91 | if !bytes.Equal(ma, mb) { 92 | t.Fatal("bytes are different") 93 | } 94 | } 95 | 96 | func TestGTMarshal(t *testing.T) { 97 | _, Ga, err := RandomGT(rand.Reader) 98 | if err != nil { 99 | t.Fatal(err) 100 | } 101 | ma := Ga.Marshal() 102 | 103 | Gb := new(GT) 104 | _, err = Gb.Unmarshal(ma) 105 | if err != nil { 106 | t.Fatal(err) 107 | } 108 | mb := Gb.Marshal() 109 | 110 | if !bytes.Equal(ma, mb) { 111 | t.Fatal("bytes are different") 112 | } 113 | } 114 | 115 | func TestBilinearity(t *testing.T) { 116 | for i := 0; i < 2; i++ { 117 | a, p1, _ := RandomG1(rand.Reader) 118 | b, p2, _ := RandomG2(rand.Reader) 119 | e1 := Pair(p1, p2) 120 | 121 | e2 := Pair(&G1{curveGen}, &G2{twistGen}) 122 | e2.ScalarMult(e2, a) 123 | e2.ScalarMult(e2, b) 124 | 125 | if *e1.p != *e2.p { 126 | t.Fatalf("bad pairing result: %s", e1) 127 | } 128 | } 129 | } 130 | 131 | func TestTripartiteDiffieHellman(t *testing.T) { 132 | a, _ := rand.Int(rand.Reader, Order) 133 | b, _ := rand.Int(rand.Reader, Order) 134 | c, _ := rand.Int(rand.Reader, Order) 135 | 136 | pa, pb, pc := new(G1), new(G1), new(G1) 137 | qa, qb, qc := new(G2), new(G2), new(G2) 138 | 139 | pa.Unmarshal(new(G1).ScalarBaseMult(a).Marshal()) 140 | qa.Unmarshal(new(G2).ScalarBaseMult(a).Marshal()) 141 | pb.Unmarshal(new(G1).ScalarBaseMult(b).Marshal()) 142 | qb.Unmarshal(new(G2).ScalarBaseMult(b).Marshal()) 143 | pc.Unmarshal(new(G1).ScalarBaseMult(c).Marshal()) 144 | qc.Unmarshal(new(G2).ScalarBaseMult(c).Marshal()) 145 | 146 | k1 := Pair(pb, qc) 147 | k1.ScalarMult(k1, a) 148 | k1Bytes := k1.Marshal() 149 | 150 | k2 := Pair(pc, qa) 151 | k2.ScalarMult(k2, b) 152 | k2Bytes := k2.Marshal() 153 | 154 | k3 := Pair(pa, qb) 155 | k3.ScalarMult(k3, c) 156 | k3Bytes := k3.Marshal() 157 | 158 | if !bytes.Equal(k1Bytes, k2Bytes) || !bytes.Equal(k2Bytes, k3Bytes) { 159 | t.Errorf("keys didn't agree") 160 | } 161 | } 162 | 163 | func TestSelfAddG1(t *testing.T) { 164 | _, Ga, err := RandomG1(rand.Reader) 165 | if err != nil { 166 | t.Fatal(err) 167 | } 168 | 169 | Gb := &G1{curveGen} 170 | Gb.p.Double(Ga.p) 171 | mb := Gb.Marshal() 172 | 173 | Ga.Add(Ga, Ga) 174 | ma := Ga.Marshal() 175 | 176 | if !bytes.Equal(ma, mb) { 177 | t.Fatal("bytes are different") 178 | } 179 | } 180 | 181 | func TestSelfAddG2(t *testing.T) { 182 | _, Ga, err := RandomG2(rand.Reader) 183 | if err != nil { 184 | t.Fatal(err) 185 | } 186 | 187 | Gb := &G2{twistGen} 188 | Gb.p.Double(Ga.p) 189 | mb := Gb.Marshal() 190 | 191 | Ga.Add(Ga, Ga) 192 | ma := Ga.Marshal() 193 | 194 | if !bytes.Equal(ma, mb) { 195 | t.Fatal("bytes are different") 196 | } 197 | } 198 | 199 | func TestDirtyUnmarshal(t *testing.T) { 200 | _, Ga, err := RandomG2(rand.Reader) 201 | if err != nil { 202 | t.Fatal(err) 203 | } 204 | ma := Ga.Marshal() 205 | 206 | if _, err := Ga.Unmarshal(ma); err != nil { 207 | t.Fatal(err) 208 | } 209 | } 210 | 211 | //// xiToPSquaredMinus1Over3 is ξ^((p²-1)/3) where ξ = bi. 212 | //func TestXiToPSquaredMinus1Over3(t *testing.T) { 213 | // one := new(big.Int).SetInt64(1) 214 | // three := new(big.Int).SetInt64(3) 215 | // p2 := new(big.Int).Mul(p, p) 216 | // p2.Sub(p2, one) 217 | // p2.Div(p2, three) 218 | // 219 | // a := gfP2{bi, *newGFp(0)} 220 | // 221 | // b := new(gfP2).GFp2Exp(&a, p2) 222 | // 223 | // fmt.Println(b) 224 | // b.y.Println() 225 | // var c gfP 226 | // montDecode(&c, &b.y) 227 | // c.Println() 228 | //} 229 | // 230 | //// xiTo2PSquaredMinus2Over3 is ξ^((2p²-2)/3) where ξ = bi (a cubic root of unity, mod p). 231 | //func TestXiTo2PSquaredMinus2Over3(t *testing.T) { 232 | // one := new(big.Int).SetInt64(1) 233 | // two := new(big.Int).SetInt64(2) 234 | // three := new(big.Int).SetInt64(3) 235 | // p2 := new(big.Int).Mul(p, p) 236 | // p2.Sub(p2, one) 237 | // p2.Mul(p2, two) 238 | // p2.Div(p2, three) 239 | // 240 | // a := gfP2{bi, *newGFp(0)} 241 | // 242 | // b := new(gfP2).GFp2Exp(&a, p2) 243 | // 244 | // fmt.Println(b) 245 | // b.y.Println() 246 | // 247 | // var c gfP 248 | // montDecode(&c, &b.y) 249 | // c.Println() 250 | // 251 | // 252 | //} 253 | // 254 | //// xiToPSquaredMinus1Over6 is ξ^((1p²-1)/6) where ξ = bi (a cubic root of -1, mod p). 255 | //func TestXiToPSquaredMinus1Over6(t *testing.T) { 256 | // one := new(big.Int).SetInt64(1) 257 | // six := new(big.Int).SetInt64(6) 258 | // p2 := new(big.Int).Mul(p, p) 259 | // p2.Sub(p2, one) 260 | // p2.Div(p2, six) 261 | // 262 | // a := gfP2{bi, *newGFp(0)} 263 | // 264 | // b := new(gfP2).GFp2Exp(&a, p2) 265 | // 266 | // fmt.Println(b) 267 | // b.y.Println() 268 | // var c gfP 269 | // montDecode(&c, &b.y) 270 | // c.Println() 271 | //} 272 | // 273 | //// xiToPMinus1Over2 is ξ^((p-1)/2) where ξ = bi. 274 | //func TestXiToPMinus1Over2(t *testing.T) { 275 | // one := new(big.Int).SetInt64(1) 276 | // two := new(big.Int).SetInt64(2) 277 | // psubone := new(big.Int).Sub(p, one) 278 | // psubone.Div(psubone, two) 279 | // 280 | // a := gfP2{bi, *newGFp(0)} 281 | // 282 | // b := new(gfP2).GFp2Exp(&a, psubone) 283 | // 284 | // fmt.Println(b) 285 | // b.y.Println() 286 | // var c gfP 287 | // montDecode(&c, &b.y) 288 | // c.Println() 289 | //} 290 | // 291 | //// xiToPMinus1Over3 is ξ^((p-1)/3) where ξ = bi. 292 | //func TestXiToPMinus1Over3(t *testing.T) { 293 | // one := new(big.Int).SetInt64(1) 294 | // three := new(big.Int).SetInt64(3) 295 | // psubone := new(big.Int).Sub(p, one) 296 | // psubone.Div(psubone, three) 297 | // 298 | // a := gfP2{bi, *newGFp(0)} 299 | // 300 | // b := new(gfP2).GFp2Exp(&a, psubone) 301 | // fmt.Println(b) 302 | // b.y.Println() 303 | // var c gfP 304 | // montDecode(&c, &b.y) 305 | // c.Println() 306 | //} 307 | // 308 | //// xiTo2PMinus2Over3 is ξ^((2p-2)/3) where ξ = bi. 309 | //func TestXiTo2PMinus2Over3(t *testing.T) { 310 | // one := new(big.Int).SetInt64(1) 311 | // two := new(big.Int).SetInt64(2) 312 | // three := new(big.Int).SetInt64(3) 313 | // psubone := new(big.Int).Sub(p, one) 314 | // psubone.Mul(psubone, two) 315 | // psubone.Div(psubone, three) 316 | // 317 | // a := gfP2{bi, *newGFp(0)} 318 | // 319 | // b := new(gfP2).GFp2Exp(&a, psubone) 320 | // 321 | // fmt.Println(b) 322 | // b.y.Println() 323 | // var c gfP 324 | // montDecode(&c, &b.y) 325 | // c.Println() 326 | //} 327 | // 328 | //// xiToPMinus1Over6 is ξ^((p-1)/6) where ξ = bi. 329 | //func TestXiToPMinus1Over6(t *testing.T) { 330 | // one := new(big.Int).SetInt64(1) 331 | // six := new(big.Int).SetInt64(6) 332 | // psubone := new(big.Int).Sub(p, one) 333 | // psubone.Div(psubone, six) 334 | // 335 | // a := gfP2{bi, *newGFp(0)} 336 | // 337 | // b := new(gfP2).GFp2Exp(&a, psubone) 338 | // 339 | // fmt.Println(b) 340 | // b.y.Println() 341 | // var c gfP 342 | // montDecode(&c, &b.y) 343 | // c.Println() 344 | //} 345 | 346 | //func TestGens(t *testing.T) { 347 | // // s is the Montgomery encoding of the square root of -3. Then, s = sqrt(-3) * 2^256 mod p. 348 | // negThree := newGFp(-3) 349 | // s := new(gfP) 350 | // s.Sqrt(negThree) 351 | // fmt.Println(s.String()) 352 | // // sMinus1Over2 is the Montgomery encoding of (s-1)/2. Then, sMinus1Over2 = ( (s-1) / 2) * 2^256 mod p. 353 | // sMinus1Over2 := new(gfP) 354 | // sMinus1Over2.Set(s) 355 | // one := newGFp(1) 356 | // gfpSub(sMinus1Over2, s, one) 357 | // two := newGFp(2) 358 | // inverse := new(gfP) 359 | // inverse.Invert(two) 360 | // gfpMul(sMinus1Over2, sMinus1Over2, inverse) 361 | // fmt.Println(sMinus1Over2.String()) 362 | //} 363 | 364 | func BenchmarkG1(b *testing.B) { 365 | x, _ := rand.Int(rand.Reader, Order) 366 | b.ResetTimer() 367 | 368 | for i := 0; i < b.N; i++ { 369 | new(G1).ScalarBaseMult(x) 370 | } 371 | } 372 | 373 | func BenchmarkG2(b *testing.B) { 374 | x, _ := rand.Int(rand.Reader, Order) 375 | b.ResetTimer() 376 | 377 | for i := 0; i < b.N; i++ { 378 | new(G2).ScalarBaseMult(x) 379 | } 380 | } 381 | 382 | func BenchmarkGT(b *testing.B) { 383 | x, _ := rand.Int(rand.Reader, Order) 384 | b.ResetTimer() 385 | 386 | for i := 0; i < b.N; i++ { 387 | new(GT).ScalarBaseMult(x) 388 | } 389 | } 390 | 391 | func BenchmarkPairing(b *testing.B) { 392 | for i := 0; i < b.N; i++ { 393 | Pair(&G1{curveGen}, &G2{twistGen}) 394 | } 395 | } 396 | 397 | func TestMiller(t *testing.T) { 398 | gt := Pair(&G1{curveGen}, &G2{twistGen}) 399 | 400 | fmt.Println(gt.String()) 401 | } 402 | -------------------------------------------------------------------------------- /sm/sm2/sm2.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 cetc-30. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package sm2 implements china crypto standards. 6 | package sm2 7 | 8 | import ( 9 | "crypto" 10 | "errors" 11 | "github.com/xlcetc/cryptogm/elliptic/sm2curve" 12 | "github.com/xlcetc/cryptogm/sm/sm3" 13 | "io" 14 | "math/big" 15 | ) 16 | 17 | type PublicKey struct { 18 | sm2curve.Curve 19 | X, Y *big.Int 20 | PreComputed *[37][64 * 8]uint64 //precomputation 21 | } 22 | 23 | type PrivateKey struct { 24 | PublicKey 25 | D *big.Int 26 | DInv *big.Int //(1+d)^-1 27 | } 28 | 29 | var generateRandK = _generateRandK 30 | 31 | //optMethod includes some optimized methods. 32 | type optMethod interface { 33 | // CombinedMult implements fast multiplication S1*g + S2*p (g - generator, p - arbitrary point) 34 | CombinedMult(Precomputed *[37][64 * 8]uint64, baseScalar, scalar []byte) (x, y *big.Int) 35 | // InitPubKeyTable implements precomputed table of public key 36 | InitPubKeyTable(x, y *big.Int) (Precomputed *[37][64 * 8]uint64) 37 | // PreScalarMult implements fast multiplication of public key 38 | PreScalarMult(Precomputed *[37][64 * 8]uint64, scalar []byte) (x, y *big.Int) 39 | } 40 | 41 | // The SM2's private key contains the public key 42 | func (priv *PrivateKey) Public() crypto.PublicKey { 43 | return &priv.PublicKey 44 | } 45 | 46 | var one = new(big.Int).SetInt64(1) 47 | 48 | func randFieldElement(c sm2curve.Curve, rand io.Reader) (k *big.Int, err error) { 49 | params := c.Params() 50 | b := make([]byte, params.BitSize/8+8) 51 | _, err = io.ReadFull(rand, b) 52 | if err != nil { 53 | return 54 | } 55 | k = new(big.Int).SetBytes(b) 56 | n := new(big.Int).Sub(params.N, one) 57 | k.Mod(k, n) 58 | k.Add(k, one) 59 | return 60 | } 61 | 62 | func GenerateKey(rand io.Reader) (*PrivateKey, error) { 63 | c := sm2curve.P256() 64 | 65 | k := _generateRandK(rand, c) 66 | priv := new(PrivateKey) 67 | priv.PublicKey.Curve = c 68 | priv.D = k 69 | //(1+d)^-1 70 | priv.DInv = new(big.Int).Add(k, one) 71 | priv.DInv.ModInverse(priv.DInv, c.Params().N) 72 | priv.PublicKey.X, priv.PublicKey.Y = c.ScalarBaseMult(k.Bytes()) 73 | if opt, ok := c.(optMethod); ok { 74 | priv.PreComputed = opt.InitPubKeyTable(priv.PublicKey.X, priv.PublicKey.Y) 75 | } 76 | return priv, nil 77 | } 78 | 79 | var errZeroParam = errors.New("zero parameter") 80 | 81 | func _generateRandK(rand io.Reader, c sm2curve.Curve) (k *big.Int) { 82 | params := c.Params() 83 | two := big.NewInt(2) 84 | b := make([]byte, params.BitSize/8+8) 85 | _, err := io.ReadFull(rand, b) 86 | if err != nil { 87 | return 88 | } 89 | k = new(big.Int).SetBytes(b) 90 | n := new(big.Int).Sub(params.N, two) 91 | k.Mod(k, n) 92 | return 93 | } 94 | 95 | func getZById(pub *PublicKey, id []byte) []byte { 96 | c := sm2curve.P256() 97 | var lena = uint16(len(id) * 8) //bit len of IDA 98 | var ENTLa = []byte{byte(lena >> 8), byte(lena)} 99 | var z = make([]byte, 0, 1024) 100 | 101 | //判断公钥x,y坐标长度是否小于32字节,若小于则在前面补0 102 | xBuf := pub.X.Bytes() 103 | yBuf := pub.Y.Bytes() 104 | 105 | xPadding := make([]byte, 32) 106 | yPadding := make([]byte, 32) 107 | 108 | if n := len(xBuf); n < 32 { 109 | xBuf = append(xPadding[:32-n], xBuf...) 110 | } 111 | 112 | if n := len(yBuf); n < 32 { 113 | yBuf = append(yPadding[:32-n], yBuf...) 114 | } 115 | 116 | var SM2PARAM_A, _ = new(big.Int).SetString("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC", 16) 117 | 118 | z = append(z, ENTLa...) 119 | z = append(z, id...) 120 | z = append(z, SM2PARAM_A.Bytes()...) 121 | z = append(z, c.Params().B.Bytes()...) 122 | z = append(z, c.Params().Gx.Bytes()...) 123 | z = append(z, c.Params().Gy.Bytes()...) 124 | z = append(z, xBuf...) 125 | z = append(z, yBuf...) 126 | 127 | //h := sm3.New() 128 | hash := sm3.SumSM3(z) 129 | return hash[:] 130 | } 131 | 132 | //Za = sm3(ENTL||IDa||a||b||Gx||Gy||Xa||Xy) 133 | func getZ(pub *PublicKey) []byte { 134 | return getZById(pub, []byte("1234567812345678")) 135 | } 136 | 137 | func Sign(rand io.Reader, priv *PrivateKey, msg []byte) (r, s *big.Int, err error) { 138 | var one = new(big.Int).SetInt64(1) 139 | //if len(hash) < 32 { 140 | // err = errors.New("The length of hash has short than what SM2 need.") 141 | // return 142 | //} 143 | 144 | var m = make([]byte, 32+len(msg)) 145 | copy(m, getZ(&priv.PublicKey)) 146 | copy(m[32:], msg) 147 | 148 | hash := sm3.SumSM3(m) 149 | e := new(big.Int).SetBytes(hash[:]) 150 | k := generateRandK(rand, priv.PublicKey.Curve) 151 | 152 | x1, _ := priv.PublicKey.Curve.ScalarBaseMult(k.Bytes()) 153 | 154 | n := priv.PublicKey.Curve.Params().N 155 | 156 | r = new(big.Int).Add(e, x1) 157 | 158 | r.Mod(r, n) 159 | 160 | s1 := new(big.Int).Mul(r, priv.D) 161 | s1.Sub(k, s1) 162 | 163 | s2 := new(big.Int) 164 | if priv.DInv == nil { 165 | s2 = s2.Add(one, priv.D) 166 | s2.ModInverse(s2, n) 167 | } else { 168 | s2 = priv.DInv 169 | } 170 | 171 | s = new(big.Int).Mul(s1, s2) 172 | s.Mod(s, n) 173 | 174 | return 175 | } 176 | 177 | func SignWithDigest(rand io.Reader, priv *PrivateKey, digest []byte) (r, s *big.Int, err error) { 178 | var one = new(big.Int).SetInt64(1) 179 | //if len(hash) < 32 { 180 | // err = errors.New("The length of hash has short than what SM2 need.") 181 | // return 182 | //} 183 | 184 | e := new(big.Int).SetBytes(digest) 185 | k := generateRandK(rand, priv.PublicKey.Curve) 186 | 187 | x1, _ := priv.PublicKey.Curve.ScalarBaseMult(k.Bytes()) 188 | 189 | n := priv.PublicKey.Curve.Params().N 190 | 191 | r = new(big.Int).Add(e, x1) 192 | 193 | r.Mod(r, n) 194 | 195 | s1 := new(big.Int).Mul(r, priv.D) 196 | s1.Mod(s1, n) 197 | s1.Sub(k, s1) 198 | s1.Mod(s1, n) 199 | 200 | s2 := new(big.Int) 201 | if priv.DInv == nil { 202 | s2 = s2.Add(one, priv.D) 203 | s2.ModInverse(s2, n) 204 | } else { 205 | s2 = priv.DInv 206 | } 207 | 208 | s = new(big.Int).Mul(s1, s2) 209 | s.Mod(s, n) 210 | 211 | return 212 | } 213 | 214 | func Verify(pub *PublicKey, msg []byte, r, s *big.Int) bool { 215 | c := pub.Curve 216 | N := c.Params().N 217 | 218 | if r.Sign() <= 0 || s.Sign() <= 0 { 219 | return false 220 | } 221 | if r.Cmp(N) >= 0 || s.Cmp(N) >= 0 { 222 | return false 223 | } 224 | 225 | n := c.Params().N 226 | 227 | var m = make([]byte, 32+len(msg)) 228 | copy(m, getZ(pub)) 229 | copy(m[32:], msg) 230 | //h := sm3.New() 231 | //hash := h.Sum(m) 232 | hash := sm3.SumSM3(m) 233 | e := new(big.Int).SetBytes(hash[:]) 234 | 235 | t := new(big.Int).Add(r, s) 236 | 237 | // Check if implements S1*g + S2*p 238 | //Using fast multiplication CombinedMult. 239 | var x1 *big.Int 240 | if opt, ok := c.(optMethod); ok && (pub.PreComputed != nil) { 241 | x1, _ = opt.CombinedMult(pub.PreComputed, s.Bytes(), t.Bytes()) 242 | } else { 243 | x11, y11 := c.ScalarMult(pub.X, pub.Y, t.Bytes()) 244 | x12, y12 := c.ScalarBaseMult(s.Bytes()) 245 | x1, _ = c.Add(x11, y11, x12, y12) 246 | } 247 | 248 | x := new(big.Int).Add(e, x1) 249 | x = x.Mod(x, n) 250 | 251 | return x.Cmp(r) == 0 252 | } 253 | 254 | func VerifyWithDigest(pub *PublicKey, digest []byte, r, s *big.Int) bool { 255 | c := pub.Curve 256 | N := c.Params().N 257 | 258 | if r.Sign() <= 0 || s.Sign() <= 0 { 259 | return false 260 | } 261 | if r.Cmp(N) >= 0 || s.Cmp(N) >= 0 { 262 | return false 263 | } 264 | 265 | n := pub.Curve.Params().N 266 | 267 | e := new(big.Int).SetBytes(digest) 268 | 269 | t := new(big.Int).Add(r, s) 270 | // Check if implements S1*g + S2*p 271 | //Using fast multiplication CombinedMult. 272 | var x1 *big.Int 273 | if opt, ok := c.(optMethod); ok && (pub.PreComputed != nil) { 274 | x1, _ = opt.CombinedMult(pub.PreComputed, s.Bytes(), t.Bytes()) 275 | } else { 276 | x11, y11 := c.ScalarMult(pub.X, pub.Y, t.Bytes()) 277 | x12, y12 := c.ScalarBaseMult(s.Bytes()) 278 | x1, _ = c.Add(x11, y11, x12, y12) 279 | } 280 | x := new(big.Int).Add(e, x1) 281 | x = x.Mod(x, n) 282 | 283 | return x.Cmp(r) == 0 284 | } 285 | 286 | type zr struct { 287 | io.Reader 288 | } 289 | 290 | func (z *zr) Read(dst []byte) (n int, err error) { 291 | for i := range dst { 292 | dst[i] = 0 293 | } 294 | return len(dst), nil 295 | } 296 | 297 | var zeroReader = &zr{} 298 | 299 | //func OptSign(rand io.Reader, priv *PrivateKey, msg []byte) (r, s *big.Int, err error) { 300 | // //var one = new(big.Int).SetInt64(1) 301 | // //if len(hash) < 32 { 302 | // // err = errors.New("The length of hash has short than what SM2 need.") 303 | // // return 304 | // //} 305 | // 306 | // var m = make([]byte, 32+len(msg)) 307 | // copy(m, getZ(&priv.PublicKey)) 308 | // copy(m[32:], msg) 309 | // 310 | // //h := sm3.New() 311 | // //hash := h.Sum(m) 312 | // hash := sm3.SumSM3(m) 313 | // e := new(big.Int).SetBytes(hash[:]) 314 | // k := generateRandK(rand, priv.PublicKey.Curve) 315 | // 316 | // x1, _ := priv.PublicKey.Curve.ScalarBaseMult(k.Bytes()) 317 | // 318 | // n := priv.PublicKey.Curve.Params().N 319 | // 320 | // r = new(big.Int).Add(e, x1) 321 | // 322 | // r.Mod(r, n) 323 | // 324 | // s1 := new(big.Int).Mul(r, priv.D) 325 | // //s1.Mod(s1, n) 326 | // s1.Sub(k, s1) 327 | // s1.Mod(s1, n) 328 | // 329 | // //s2 := new(big.Int).Add(one, priv.D) 330 | // //s2.Mod(s2, n) 331 | // //s2.ModInverse(s2, n) 332 | // s = new(big.Int).Mul(s1, priv.DInv) 333 | // s.Mod(s, n) 334 | // 335 | // return 336 | //} 337 | // 338 | //func OptVerify(pub *PublicKey, msg []byte, r, s *big.Int) bool { 339 | // c := pub.Curve 340 | // N := c.Params().N 341 | // 342 | // if r.Sign() <= 0 || s.Sign() <= 0 { 343 | // return false 344 | // } 345 | // if r.Cmp(N) >= 0 || s.Cmp(N) >= 0 { 346 | // return false 347 | // } 348 | // 349 | // n := c.Params().N 350 | // 351 | // var m = make([]byte, 32+len(msg)) 352 | // copy(m, getZ(pub)) 353 | // copy(m[32:], msg) 354 | // //h := sm3.New() 355 | // //hash := h.Sum(m) 356 | // hash := sm3.SumSM3(m) 357 | // e := new(big.Int).SetBytes(hash[:]) 358 | // 359 | // t := new(big.Int).Add(r, s) 360 | // 361 | // // Check if implements S1*g + S2*p 362 | // //Using fast multiplication CombinedMult. 363 | // var x1 *big.Int 364 | // if opt, ok := c.(optMethod); ok { 365 | // //x11, y11 := opt.PreScalarMult(pub.PreComputed,t.Bytes()) 366 | // //x12, y12 := c.ScalarBaseMult(s.Bytes()) 367 | // //x1, _ = c.Add(x11, y11, x12, y12) 368 | // x1, _ = opt.CombinedMult(pub.PreComputed, s.Bytes(), t.Bytes()) 369 | // } else { 370 | // x11, y11 := c.ScalarMult(pub.X, pub.Y, t.Bytes()) 371 | // x12, y12 := c.ScalarBaseMult(s.Bytes()) 372 | // x1, _ = c.Add(x11, y11, x12, y12) 373 | // } 374 | // 375 | // x := new(big.Int).Add(e, x1) 376 | // x = x.Mod(x, n) 377 | // 378 | // return x.Cmp(r) == 0 379 | //} 380 | -------------------------------------------------------------------------------- /elliptic/sm2curve/elliptic.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package elliptic implements several standard elliptic curves over prime 6 | // fields. 7 | package sm2curve 8 | 9 | // This package operates, internally, on Jacobian coordinates. For a given 10 | // (x, y) position on the curve, the Jacobian coordinates are (x1, y1, z1) 11 | // where x = x1/z1² and y = y1/z1³. The greatest speedups come when the whole 12 | // calculation can be performed within the transform (as in ScalarMult and 13 | // ScalarBaseMult). But even for Add and Double, it's faster to apply and 14 | // reverse the transform than to operate in affine coordinates. 15 | 16 | import ( 17 | "io" 18 | "math/big" 19 | "sync" 20 | ) 21 | 22 | // A Curve represents a short-form Weierstrass curve with a=-3. 23 | // See http://www.hyperelliptic.org/EFD/g1p/auto-shortw.html 24 | type Curve interface { 25 | // Params returns the parameters for the curve. 26 | Params() *CurveParams 27 | // IsOnCurve reports whether the given (x,y) lies on the curve. 28 | IsOnCurve(x, y *big.Int) bool 29 | // Add returns the sum of (x1,y1) and (x2,y2) 30 | Add(x1, y1, x2, y2 *big.Int) (x, y *big.Int) 31 | // Double returns 2*(x,y) 32 | Double(x1, y1 *big.Int) (x, y *big.Int) 33 | // ScalarMult returns k*(Bx,By) where k is a number in big-endian form. 34 | ScalarMult(x1, y1 *big.Int, k []byte) (x, y *big.Int) 35 | // ScalarBaseMult returns k*G, where G is the base point of the group 36 | // and k is an integer in big-endian form. 37 | ScalarBaseMult(k []byte) (x, y *big.Int) 38 | } 39 | 40 | // CurveParams contains the parameters of an elliptic curve and also provides 41 | // a generic, non-constant time implementation of Curve. 42 | type CurveParams struct { 43 | P *big.Int // the order of the underlying field 44 | N *big.Int // the order of the base point 45 | B *big.Int // the constant of the curve equation 46 | Gx, Gy *big.Int // (x,y) of the base point 47 | BitSize int // the size of the underlying field 48 | Name string // the canonical name of the curve 49 | } 50 | 51 | func (curve *CurveParams) Params() *CurveParams { 52 | return curve 53 | } 54 | 55 | func (curve *CurveParams) IsOnCurve(x, y *big.Int) bool { 56 | // y² = x³ - 3x + b 57 | y2 := new(big.Int).Mul(y, y) 58 | y2.Mod(y2, curve.P) 59 | 60 | x3 := new(big.Int).Mul(x, x) 61 | x3.Mul(x3, x) 62 | 63 | threeX := new(big.Int).Lsh(x, 1) 64 | threeX.Add(threeX, x) 65 | 66 | x3.Sub(x3, threeX) 67 | x3.Add(x3, curve.B) 68 | x3.Mod(x3, curve.P) 69 | 70 | return x3.Cmp(y2) == 0 71 | } 72 | 73 | // zForAffine returns a Jacobian Z value for the affine point (x, y). If x and 74 | // y are zero, it assumes that they represent the point at infinity because (0, 75 | // 0) is not on the any of the curves handled here. 76 | func zForAffine(x, y *big.Int) *big.Int { 77 | z := new(big.Int) 78 | if x.Sign() != 0 || y.Sign() != 0 { 79 | z.SetInt64(1) 80 | } 81 | return z 82 | } 83 | 84 | // affineFromJacobian reverses the Jacobian transform. See the comment at the 85 | // top of the file. If the point is ∞ it returns 0, 0. 86 | func (curve *CurveParams) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) { 87 | if z.Sign() == 0 { 88 | return new(big.Int), new(big.Int) 89 | } 90 | 91 | zinv := new(big.Int).ModInverse(z, curve.P) 92 | zinvsq := new(big.Int).Mul(zinv, zinv) 93 | 94 | xOut = new(big.Int).Mul(x, zinvsq) 95 | xOut.Mod(xOut, curve.P) 96 | zinvsq.Mul(zinvsq, zinv) 97 | yOut = new(big.Int).Mul(y, zinvsq) 98 | yOut.Mod(yOut, curve.P) 99 | return 100 | } 101 | 102 | func (curve *CurveParams) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) { 103 | z1 := zForAffine(x1, y1) 104 | z2 := zForAffine(x2, y2) 105 | return curve.affineFromJacobian(curve.addJacobian(x1, y1, z1, x2, y2, z2)) 106 | } 107 | 108 | // addJacobian takes two points in Jacobian coordinates, (x1, y1, z1) and 109 | // (x2, y2, z2) and returns their sum, also in Jacobian form. 110 | func (curve *CurveParams) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int, *big.Int, *big.Int) { 111 | // See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl 112 | x3, y3, z3 := new(big.Int), new(big.Int), new(big.Int) 113 | if z1.Sign() == 0 { 114 | x3.Set(x2) 115 | y3.Set(y2) 116 | z3.Set(z2) 117 | return x3, y3, z3 118 | } 119 | if z2.Sign() == 0 { 120 | x3.Set(x1) 121 | y3.Set(y1) 122 | z3.Set(z1) 123 | return x3, y3, z3 124 | } 125 | 126 | z1z1 := new(big.Int).Mul(z1, z1) 127 | z1z1.Mod(z1z1, curve.P) 128 | z2z2 := new(big.Int).Mul(z2, z2) 129 | z2z2.Mod(z2z2, curve.P) 130 | 131 | u1 := new(big.Int).Mul(x1, z2z2) 132 | u1.Mod(u1, curve.P) 133 | u2 := new(big.Int).Mul(x2, z1z1) 134 | u2.Mod(u2, curve.P) 135 | h := new(big.Int).Sub(u2, u1) 136 | xEqual := h.Sign() == 0 137 | if h.Sign() == -1 { 138 | h.Add(h, curve.P) 139 | } 140 | i := new(big.Int).Lsh(h, 1) 141 | i.Mul(i, i) 142 | j := new(big.Int).Mul(h, i) 143 | 144 | s1 := new(big.Int).Mul(y1, z2) 145 | s1.Mul(s1, z2z2) 146 | s1.Mod(s1, curve.P) 147 | s2 := new(big.Int).Mul(y2, z1) 148 | s2.Mul(s2, z1z1) 149 | s2.Mod(s2, curve.P) 150 | r := new(big.Int).Sub(s2, s1) 151 | if r.Sign() == -1 { 152 | r.Add(r, curve.P) 153 | } 154 | yEqual := r.Sign() == 0 155 | if xEqual && yEqual { 156 | return curve.doubleJacobian(x1, y1, z1) 157 | } 158 | r.Lsh(r, 1) 159 | v := new(big.Int).Mul(u1, i) 160 | 161 | x3.Set(r) 162 | x3.Mul(x3, x3) 163 | x3.Sub(x3, j) 164 | x3.Sub(x3, v) 165 | x3.Sub(x3, v) 166 | x3.Mod(x3, curve.P) 167 | 168 | y3.Set(r) 169 | v.Sub(v, x3) 170 | y3.Mul(y3, v) 171 | s1.Mul(s1, j) 172 | s1.Lsh(s1, 1) 173 | y3.Sub(y3, s1) 174 | y3.Mod(y3, curve.P) 175 | 176 | z3.Add(z1, z2) 177 | z3.Mul(z3, z3) 178 | z3.Sub(z3, z1z1) 179 | z3.Sub(z3, z2z2) 180 | z3.Mul(z3, h) 181 | z3.Mod(z3, curve.P) 182 | 183 | return x3, y3, z3 184 | } 185 | 186 | func (curve *CurveParams) Double(x1, y1 *big.Int) (*big.Int, *big.Int) { 187 | z1 := zForAffine(x1, y1) 188 | return curve.affineFromJacobian(curve.doubleJacobian(x1, y1, z1)) 189 | } 190 | 191 | // doubleJacobian takes a point in Jacobian coordinates, (x, y, z), and 192 | // returns its double, also in Jacobian form. 193 | func (curve *CurveParams) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, *big.Int) { 194 | // See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b 195 | delta := new(big.Int).Mul(z, z) 196 | delta.Mod(delta, curve.P) 197 | gamma := new(big.Int).Mul(y, y) 198 | gamma.Mod(gamma, curve.P) 199 | alpha := new(big.Int).Sub(x, delta) 200 | if alpha.Sign() == -1 { 201 | alpha.Add(alpha, curve.P) 202 | } 203 | alpha2 := new(big.Int).Add(x, delta) 204 | alpha.Mul(alpha, alpha2) 205 | alpha2.Set(alpha) 206 | alpha.Lsh(alpha, 1) 207 | alpha.Add(alpha, alpha2) 208 | 209 | beta := alpha2.Mul(x, gamma) 210 | 211 | x3 := new(big.Int).Mul(alpha, alpha) 212 | beta8 := new(big.Int).Lsh(beta, 3) 213 | x3.Sub(x3, beta8) 214 | for x3.Sign() == -1 { 215 | x3.Add(x3, curve.P) 216 | } 217 | x3.Mod(x3, curve.P) 218 | 219 | z3 := new(big.Int).Add(y, z) 220 | z3.Mul(z3, z3) 221 | z3.Sub(z3, gamma) 222 | if z3.Sign() == -1 { 223 | z3.Add(z3, curve.P) 224 | } 225 | z3.Sub(z3, delta) 226 | if z3.Sign() == -1 { 227 | z3.Add(z3, curve.P) 228 | } 229 | z3.Mod(z3, curve.P) 230 | 231 | beta.Lsh(beta, 2) 232 | beta.Sub(beta, x3) 233 | if beta.Sign() == -1 { 234 | beta.Add(beta, curve.P) 235 | } 236 | y3 := alpha.Mul(alpha, beta) 237 | 238 | gamma.Mul(gamma, gamma) 239 | gamma.Lsh(gamma, 3) 240 | gamma.Mod(gamma, curve.P) 241 | 242 | y3.Sub(y3, gamma) 243 | if y3.Sign() == -1 { 244 | y3.Add(y3, curve.P) 245 | } 246 | y3.Mod(y3, curve.P) 247 | 248 | return x3, y3, z3 249 | } 250 | 251 | func (curve *CurveParams) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) { 252 | Bz := new(big.Int).SetInt64(1) 253 | x, y, z := new(big.Int), new(big.Int), new(big.Int) 254 | 255 | for _, byte := range k { 256 | for bitNum := 0; bitNum < 8; bitNum++ { 257 | x, y, z = curve.doubleJacobian(x, y, z) 258 | if byte&0x80 == 0x80 { 259 | x, y, z = curve.addJacobian(Bx, By, Bz, x, y, z) 260 | } 261 | byte <<= 1 262 | } 263 | } 264 | 265 | return curve.affineFromJacobian(x, y, z) 266 | } 267 | 268 | func (curve *CurveParams) ScalarBaseMult(k []byte) (*big.Int, *big.Int) { 269 | return curve.ScalarMult(curve.Gx, curve.Gy, k) 270 | } 271 | 272 | var mask = []byte{0xff, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f} 273 | 274 | // GenerateKey returns a public/private key pair. The private key is 275 | // generated using the given reader, which must return random data. 276 | func GenerateKey(curve Curve, rand io.Reader) (priv []byte, x, y *big.Int, err error) { 277 | N := curve.Params().N 278 | bitSize := N.BitLen() 279 | byteLen := (bitSize + 7) >> 3 280 | priv = make([]byte, byteLen) 281 | 282 | for x == nil { 283 | _, err = io.ReadFull(rand, priv) 284 | if err != nil { 285 | return 286 | } 287 | // We have to mask off any excess bits in the case that the size of the 288 | // underlying field is not a whole number of bytes. 289 | priv[0] &= mask[bitSize%8] 290 | // This is because, in tests, rand will return all zeros and we don't 291 | // want to get the point at infinity and loop forever. 292 | priv[1] ^= 0x42 293 | 294 | // If the scalar is out of range, sample another random number. 295 | if new(big.Int).SetBytes(priv).Cmp(N) >= 0 { 296 | continue 297 | } 298 | 299 | x, y = curve.ScalarBaseMult(priv) 300 | } 301 | return 302 | } 303 | 304 | // Marshal converts a point into the uncompressed form specified in section 4.3.6 of ANSI X9.62. 305 | func Marshal(curve Curve, x, y *big.Int) []byte { 306 | byteLen := (curve.Params().BitSize + 7) >> 3 307 | 308 | ret := make([]byte, 1+2*byteLen) 309 | ret[0] = 4 // uncompressed point 310 | 311 | xBytes := x.Bytes() 312 | copy(ret[1+byteLen-len(xBytes):], xBytes) 313 | yBytes := y.Bytes() 314 | copy(ret[1+2*byteLen-len(yBytes):], yBytes) 315 | return ret 316 | } 317 | 318 | // Unmarshal converts a point, serialized by Marshal, into an x, y pair. 319 | // It is an error if the point is not in uncompressed form or is not on the curve. 320 | // On error, x = nil. 321 | func Unmarshal(curve Curve, data []byte) (x, y *big.Int) { 322 | byteLen := (curve.Params().BitSize + 7) >> 3 323 | if len(data) != 1+2*byteLen { 324 | return 325 | } 326 | if data[0] != 4 { // uncompressed form 327 | return 328 | } 329 | p := curve.Params().P 330 | x = new(big.Int).SetBytes(data[1 : 1+byteLen]) 331 | y = new(big.Int).SetBytes(data[1+byteLen:]) 332 | if x.Cmp(p) >= 0 || y.Cmp(p) >= 0 { 333 | return nil, nil 334 | } 335 | if !curve.IsOnCurve(x, y) { 336 | return nil, nil 337 | } 338 | return 339 | } 340 | 341 | var initonce sync.Once 342 | 343 | func initAll() { 344 | initP256() 345 | } 346 | 347 | // P256 returns a Curve which implements sm2 curve. 348 | // 349 | // The cryptographic operations are implemented using constant-time algorithms. 350 | func P256() Curve { 351 | initonce.Do(initAll) 352 | return p256 353 | } 354 | -------------------------------------------------------------------------------- /elliptic/sm9curve/genpara/genconsts/genconsts.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "math/big" 7 | ) 8 | 9 | func bigFromBase10(s string) *big.Int { 10 | n, _ := new(big.Int).SetString(s, 10) 11 | return n 12 | } 13 | 14 | func mulPoly(coeffs []int64, x *big.Int) *big.Int { 15 | powers := make([]*big.Int, len(coeffs)) 16 | 17 | acc := new(big.Int).SetInt64(1) 18 | for i, _ := range powers { 19 | powers[i] = new(big.Int).Set(acc) 20 | acc.Mul(acc, x) 21 | } 22 | 23 | acc.SetInt64(0) 24 | temp := new(big.Int) 25 | for i, _ := range powers { 26 | temp.SetInt64(coeffs[i]).Mul(temp, powers[i]) 27 | acc.Add(acc, temp) 28 | } 29 | 30 | return acc 31 | } 32 | 33 | func printWords(in *big.Int) { 34 | words := in.Bits() 35 | 36 | for _, word := range words[:len(words)-1] { 37 | fmt.Printf("%#x, ", word) 38 | } 39 | fmt.Printf("%#x}\n\n", words[len(words)-1]) 40 | } 41 | 42 | var ( 43 | u = bigFromBase10("6518589491078791937") 44 | sm9u = bigFromBase10("6917529027646912906") //600000000058f98a 45 | bitSize = uint(64 * 4) 46 | ) 47 | 48 | func genpara() { 49 | fmt.Println("// u is the BN parameter that determines the prime.") 50 | fmt.Printf("var u = bigFromBase10(\"%v\")\n\n", u) 51 | 52 | p := mulPoly([]int64{1, 6, 24, 36, 36}, u) 53 | fmt.Println("// p is a prime over which we form a basic field: 36u⁴+36u³+24u²+6u+1.") 54 | fmt.Printf("var p = bigFromBase10(\"%v\")\n\n", p) 55 | if !p.ProbablyPrime(20) { 56 | log.Fatal("p not prime") 57 | } 58 | 59 | Order := mulPoly([]int64{1, 6, 18, 36, 36}, u) 60 | fmt.Println("// Order is the number of elements in both G₁ and G₂: 36u⁴+36u³+18u²+6u+1.") 61 | fmt.Printf("var Order = bigFromBase10(\"%v\")\n\n", Order) 62 | if !Order.ProbablyPrime(20) { 63 | log.Fatal("Order not prime") 64 | } 65 | 66 | // Create algebraic constants. 67 | 68 | // Can we build an imaginary extension 69 | temp1 := new(big.Int).SetInt64(1) 70 | temp1.Sub(p, temp1).Rsh(temp1, 1) 71 | if temp1.Bit(0) != 1 { 72 | log.Fatal("cannot build imaginary extension") 73 | } 74 | 75 | xi := newGFp2(p) 76 | xi.x.SetInt64(1) 77 | xi.y.SetInt64(3) 78 | 79 | exp := big.NewInt(1) 80 | exp.Sub(p, exp) 81 | if new(big.Int).Mod(exp, big.NewInt(6)).Sign() != 0 { 82 | log.Fatal("not divis by 6") 83 | } 84 | exp.Div(exp, big.NewInt(6)) 85 | xi1 := newGFp2(p).Exp(xi, exp).MontEncode(bitSize) 86 | fmt.Println("// xiToPMinus1Over6 is ξ^((p-1)/6) where ξ = i+3.") 87 | fmt.Print("var xiToPMinus1Over6 = ") 88 | xi1.Println() 89 | 90 | exp.SetInt64(1).Sub(p, exp).Div(p, big.NewInt(3)) 91 | xi2 := newGFp2(p).Exp(xi, exp).MontEncode(bitSize) 92 | fmt.Println("// xiToPMinus1Over3 is ξ^((p-1)/3) where ξ = i+3.") 93 | fmt.Print("var xiToPMinus1Over3 = ") 94 | xi2.Println() 95 | 96 | exp.SetInt64(1).Sub(p, exp).Div(p, big.NewInt(2)) 97 | xi3 := newGFp2(p).Exp(xi, exp).MontEncode(bitSize) 98 | fmt.Println("// xiToPMinus1Over2 is ξ^((p-1)/2) where ξ = i+3.") 99 | fmt.Print("var xiToPMinus1Over2 = ") 100 | xi3.Println() 101 | 102 | temp2 := new(big.Int).Mul(p, p) 103 | 104 | exp.SetInt64(1).Sub(temp2, exp).Div(exp, big.NewInt(3)) 105 | xi4 := newGFp2(p).Exp(xi, exp).MontEncode(bitSize) 106 | fmt.Println("// xiToPSquaredMinus1Over3 is ξ^((p²-1)/3) where ξ = i+3.") 107 | fmt.Print("var xiToPSquaredMinus1Over3 = ") 108 | xi4.PrintY() 109 | 110 | exp.SetInt64(1).Sub(temp2, exp).Add(exp, exp).Div(exp, big.NewInt(3)) 111 | xi5 := newGFp2(p).Exp(xi, exp).MontEncode(bitSize) 112 | fmt.Println("// xiTo2PSquaredMinus2Over3 is ξ^((2p²-2)/3) where ξ = i+3 (a cubic root of unity, mod p).") 113 | fmt.Print("var xiTo2PSquaredMinus2Over3 = ") 114 | xi5.PrintY() 115 | 116 | exp.SetInt64(1).Sub(temp2, exp).Div(exp, big.NewInt(6)) 117 | xi6 := newGFp2(p).Exp(xi, exp).MontEncode(bitSize) 118 | fmt.Println("// xiToPSquaredMinus1Over6 is ξ^((p²-1)/6) where ξ = i+3 (a cubic root of -1, mod p).") 119 | fmt.Print("var xiToPSquaredMinus1Over6 = ") 120 | xi6.PrintY() 121 | 122 | exp.SetInt64(1).Sub(p, exp).Add(exp, exp).Div(exp, big.NewInt(3)) 123 | xi7 := newGFp2(p).Exp(xi, exp).MontEncode(bitSize) 124 | fmt.Println("// xiTo2PMinus2Over3 is ξ^((2p-2)/3) where ξ = i+3.") 125 | fmt.Print("var xiTo2PMinus2Over3 = ") 126 | xi7.Println() 127 | 128 | //xi8 := new(gfP2) 129 | //xi8.p = p 130 | //xi8.x = big.NewInt(0) 131 | //xi8.y,_ = new(big.Int).SetString("2338e7dbf670f3602324553813044cae8580d5c665af30b5887f568e3cb7f583",16) 132 | //xi9 := xi8.MontEncode(bitSize) 133 | //xi9.PrintY() 134 | 135 | // Create constants for montgomery multiplication. 136 | fmt.Println("// p2 is p, represented as little-endian 64-bit words.") 137 | fmt.Printf("var p2 = [%v]uint64{", bitSize/64) 138 | printWords(p) 139 | 140 | pMinusTwo := big.NewInt(2) 141 | pMinusTwo.Sub(p, pMinusTwo) 142 | fmt.Println("// pMinusTwo is p-2.") 143 | fmt.Printf("var pMinusTwo = [%v]uint64{", bitSize/64) 144 | printWords(pMinusTwo) 145 | 146 | R := big.NewInt(1) 147 | R.Lsh(R, bitSize) 148 | 149 | np := new(big.Int).Set(p) 150 | np.ModInverse(np, R).Neg(np).Mod(np, R) 151 | fmt.Printf("// np is the negative inverse of p, mod 2^%v.\n", bitSize) 152 | fmt.Printf("var np = [%v]uint64{", bitSize/64) 153 | printWords(np) 154 | 155 | rN1 := new(big.Int).Set(R) 156 | rN1.Mod(rN1, p).ModInverse(rN1, p) 157 | fmt.Printf("// rN1 is R^-1 where R = 2^%v mod p.\n", bitSize) 158 | fmt.Print("var rN1 = &gfP{") 159 | printWords(rN1) 160 | 161 | r2 := new(big.Int).Mul(R, R) 162 | r2.Mod(r2, p) 163 | fmt.Printf("// r2 is R^2 where R = 2^%v mod p.\n", bitSize) 164 | fmt.Printf("var r2 = &gfP{") 165 | printWords(r2) 166 | 167 | r3 := new(big.Int).Mul(R, R) 168 | r3.Mul(r3, R).Mod(r3, p) 169 | fmt.Printf("// r3 is R^3 where R = 2^%v mod p.\n", bitSize) 170 | fmt.Printf("var r3 = &gfP{") 171 | printWords(r3) 172 | 173 | sixPlusTwo := new(big.Int).Mul(u, big.NewInt(6)) 174 | sixPlusTwo.Add(sixPlusTwo, big.NewInt(2)) 175 | naf := make([]int8, 0) 176 | for sixPlusTwo.Sign() != 0 { 177 | if sixPlusTwo.Bit(0) == 1 { 178 | x := 2 - int8(2*sixPlusTwo.Bit(1)+sixPlusTwo.Bit(0)) 179 | 180 | naf = append(naf, x) 181 | sixPlusTwo.Sub(sixPlusTwo, big.NewInt(int64(x))) 182 | } else { 183 | naf = append(naf, 0) 184 | } 185 | sixPlusTwo.Rsh(sixPlusTwo, 1) 186 | } 187 | fmt.Println("// sixuPlus2NAF is 6u+2 in non-adjacent form.") 188 | fmt.Printf("var sixuPlus2NAF = %#v\n\n", naf) 189 | } 190 | 191 | func gensm9para() { 192 | fmt.Println("// u is the BN parameter that determines the prime.") 193 | fmt.Printf("var u = bigFromBase10(\"%v\")\n\n", sm9u) 194 | 195 | p := mulPoly([]int64{1, 6, 24, 36, 36}, sm9u) 196 | fmt.Println("// p is a prime over which we form a basic field: 36u⁴+36u³+24u²+6u+1.") 197 | fmt.Printf("var p = bigFromBase10(\"%v\")\n\n", p) 198 | if !p.ProbablyPrime(20) { 199 | log.Fatal("p not prime") 200 | } 201 | 202 | Order := mulPoly([]int64{1, 6, 18, 36, 36}, sm9u) 203 | fmt.Println("// Order is the number of elements in both G₁ and G₂: 36u⁴+36u³+18u²+6u+1.") 204 | fmt.Printf("var Order = bigFromBase10(\"%v\")\n\n", Order) 205 | if !Order.ProbablyPrime(20) { 206 | log.Fatal("Order not prime") 207 | } 208 | 209 | // Create algebraic constants. 210 | bi := newGFp2(p) 211 | b, _ := new(big.Int).SetString("5b2000000151d378eb01d5a7fac763a290f949a58d3d776df2b7cd93f1a8a2be", 16) 212 | bi.x.Set(b) 213 | fmt.Println("//ξ=bi, where b = (-1/2) mod p (in montEncode form).") 214 | fmt.Print("var bi = ") 215 | bi = bi.MontEncode(bitSize) 216 | bi.PrintX() 217 | 218 | // reset xi = bi 219 | xi := newGFp2(p) 220 | xi.x.Set(b) 221 | 222 | exp := big.NewInt(1) 223 | exp.Sub(p, exp) 224 | if new(big.Int).Mod(exp, big.NewInt(6)).Sign() != 0 { 225 | log.Fatal("not divis by 6") 226 | } 227 | exp.Div(exp, big.NewInt(6)) 228 | xi1 := newGFp2(p).Sm9Exp(xi, exp).MontEncode(bitSize) 229 | fmt.Println("// xiToPMinus1Over6 is ξ^((p-1)/6) where ξ = bi.") 230 | fmt.Print("var xiToPMinus1Over6 = ") 231 | xi1.PrintY() 232 | 233 | exp.SetInt64(1).Sub(p, exp).Div(p, big.NewInt(3)) 234 | xi2 := newGFp2(p).Sm9Exp(xi, exp).MontEncode(bitSize) 235 | fmt.Println("// xiToPMinus1Over3 is ξ^((p-1)/3) where ξ = bi.") 236 | fmt.Print("var xiToPMinus1Over3 = ") 237 | xi2.PrintY() 238 | 239 | exp.SetInt64(1).Sub(p, exp).Div(p, big.NewInt(2)) 240 | xi3 := newGFp2(p).Sm9Exp(xi, exp).MontEncode(bitSize) 241 | fmt.Println("// xiToPMinus1Over2 is ξ^((p-1)/2) where ξ = bi.") 242 | fmt.Print("var xiToPMinus1Over2 = ") 243 | xi3.PrintY() 244 | 245 | temp2 := new(big.Int).Mul(p, p) 246 | 247 | exp.SetInt64(1).Sub(temp2, exp).Div(exp, big.NewInt(3)) 248 | xi4 := newGFp2(p).Sm9Exp(xi, exp).MontEncode(bitSize) 249 | fmt.Println("// xiToPSquaredMinus1Over3 is ξ^((p²-1)/3) where ξ = bi.") 250 | fmt.Print("var xiToPSquaredMinus1Over3 = ") 251 | xi4.PrintY() 252 | 253 | exp.SetInt64(1).Sub(temp2, exp).Add(exp, exp).Div(exp, big.NewInt(3)) 254 | xi5 := newGFp2(p).Sm9Exp(xi, exp).MontEncode(bitSize) 255 | fmt.Println("// xiTo2PSquaredMinus2Over3 is ξ^((2p²-2)/3) where ξ = bi.") 256 | fmt.Print("var xiTo2PSquaredMinus2Over3 = ") 257 | xi5.PrintY() 258 | 259 | exp.SetInt64(1).Sub(temp2, exp).Div(exp, big.NewInt(6)) 260 | xi6 := newGFp2(p).Sm9Exp(xi, exp).MontEncode(bitSize) 261 | fmt.Println("// xiToPSquaredMinus1Over6 is ξ^((p²-1)/6) where ξ = bi.") 262 | fmt.Print("var xiToPSquaredMinus1Over6 = ") 263 | xi6.PrintY() 264 | 265 | exp.SetInt64(1).Sub(p, exp).Add(exp, exp).Div(exp, big.NewInt(3)) 266 | xi7 := newGFp2(p).Sm9Exp(xi, exp).MontEncode(bitSize) 267 | fmt.Println("// xiTo2PMinus2Over3 is ξ^((2p-2)/3) where ξ = bi.") 268 | fmt.Print("var xiTo2PMinus2Over3 = ") 269 | xi7.PrintY() 270 | 271 | // Create constants for montgomery multiplication. 272 | fmt.Println("// p2 is p, represented as little-endian 64-bit words.") 273 | fmt.Printf("var p2 = [%v]uint64{", bitSize/64) 274 | printWords(p) 275 | 276 | pMinusTwo := big.NewInt(2) 277 | pMinusTwo.Sub(p, pMinusTwo) 278 | fmt.Println("// pMinusTwo is p-2.") 279 | fmt.Printf("var pMinusTwo = [%v]uint64{", bitSize/64) 280 | printWords(pMinusTwo) 281 | 282 | R := big.NewInt(1) 283 | R.Lsh(R, bitSize) 284 | 285 | np := new(big.Int).Set(p) 286 | np.ModInverse(np, R).Neg(np).Mod(np, R) 287 | fmt.Printf("// np is the negative inverse of p, mod 2^%v.\n", bitSize) 288 | fmt.Printf("var np = [%v]uint64{", bitSize/64) 289 | printWords(np) 290 | 291 | rN1 := new(big.Int).Set(R) 292 | rN1.Mod(rN1, p).ModInverse(rN1, p) 293 | fmt.Printf("// rN1 is R^-1 where R = 2^%v mod p.\n", bitSize) 294 | fmt.Print("var rN1 = &gfP{") 295 | printWords(rN1) 296 | 297 | r2 := new(big.Int).Mul(R, R) 298 | r2.Mod(r2, p) 299 | fmt.Printf("// r2 is R^2 where R = 2^%v mod p.\n", bitSize) 300 | fmt.Printf("var r2 = &gfP{") 301 | printWords(r2) 302 | 303 | r3 := new(big.Int).Mul(R, R) 304 | r3.Mul(r3, R).Mod(r3, p) 305 | fmt.Printf("// r3 is R^3 where R = 2^%v mod p.\n", bitSize) 306 | fmt.Printf("var r3 = &gfP{") 307 | printWords(r3) 308 | 309 | sixPlusTwo := new(big.Int).Mul(sm9u, big.NewInt(6)) 310 | sixPlusTwo.Add(sixPlusTwo, big.NewInt(2)) 311 | naf := make([]int8, 0) 312 | for sixPlusTwo.Sign() != 0 { 313 | if sixPlusTwo.Bit(0) == 1 { 314 | x := 2 - int8(2*sixPlusTwo.Bit(1)+sixPlusTwo.Bit(0)) 315 | 316 | naf = append(naf, x) 317 | sixPlusTwo.Sub(sixPlusTwo, big.NewInt(int64(x))) 318 | } else { 319 | naf = append(naf, 0) 320 | } 321 | sixPlusTwo.Rsh(sixPlusTwo, 1) 322 | } 323 | fmt.Println("// sixuPlus2NAF is 6u+2 in non-adjacent form.") 324 | fmt.Printf("var sixuPlus2NAF = %#v\n\n", naf) 325 | } 326 | 327 | func main() { 328 | //genpara() 329 | gensm9para() 330 | } 331 | -------------------------------------------------------------------------------- /elliptic/sm9curve/bn256.go: -------------------------------------------------------------------------------- 1 | // Package bn256 implements a particular bilinear group. 2 | // 3 | // Bilinear groups are the basis of many of the new cryptographic protocols that 4 | // have been proposed over the past decade. They consist of a triplet of groups 5 | // (G₁, G₂ and GT) such that there exists a function e(g₁ˣ,g₂ʸ)=gTˣʸ (where gₓ 6 | // is a generator of the respective group). That function is called a pairing 7 | // function. 8 | // 9 | // This package specifically implements the Optimal Ate pairing over a 256-bit 10 | // Barreto-Naehrig curve as described in 11 | // http://cryptojedi.org/papers/dclxvi-20100714.pdf. Its output is compatible 12 | // with the implementation described in that paper. 13 | // 14 | // This package previously claimed to operate at a 128-bit security level. 15 | // However, recent improvements in attacks mean that is no longer true. See 16 | // https://moderncrypto.org/mail-archive/curves/2016/000740.html. 17 | package sm9curve 18 | 19 | import ( 20 | "crypto/rand" 21 | "errors" 22 | "io" 23 | "math/big" 24 | ) 25 | 26 | func randomK(r io.Reader) (k *big.Int, err error) { 27 | for { 28 | k, err = rand.Int(r, Order) 29 | if k.Sign() > 0 || err != nil { 30 | return 31 | } 32 | } 33 | 34 | return 35 | } 36 | 37 | // G1 is an abstract cyclic group. The zero value is suitable for use as the 38 | // output of an operation, but cannot be used as an input. 39 | type G1 struct { 40 | p *curvePoint 41 | } 42 | 43 | //Gen1 is the generator of G1. 44 | var Gen1 = &G1{curveGen} 45 | 46 | // RandomG1 returns x and g₁ˣ where x is a random, non-zero number read from r. 47 | func RandomG1(r io.Reader) (*big.Int, *G1, error) { 48 | k, err := randomK(r) 49 | if err != nil { 50 | return nil, nil, err 51 | } 52 | 53 | return k, new(G1).ScalarBaseMult(k), nil 54 | } 55 | 56 | func (g *G1) String() string { 57 | return "bn256.G1" + g.p.String() 58 | } 59 | 60 | // ScalarBaseMult sets e to g*k where g is the generator of the group and then 61 | // returns e. 62 | func (e *G1) ScalarBaseMult(k *big.Int) *G1 { 63 | if e.p == nil { 64 | e.p = &curvePoint{} 65 | } 66 | e.p.Mul(curveGen, k) 67 | return e 68 | } 69 | 70 | // ScalarMult sets e to a*k and then returns e. 71 | func (e *G1) ScalarMult(a *G1, k *big.Int) *G1 { 72 | if e.p == nil { 73 | e.p = &curvePoint{} 74 | } 75 | e.p.Mul(a.p, k) 76 | return e 77 | } 78 | 79 | // Add sets e to a+b and then returns e. 80 | func (e *G1) Add(a, b *G1) *G1 { 81 | if e.p == nil { 82 | e.p = &curvePoint{} 83 | } 84 | e.p.Add(a.p, b.p) 85 | return e 86 | } 87 | 88 | // Neg sets e to -a and then returns e. 89 | func (e *G1) Neg(a *G1) *G1 { 90 | if e.p == nil { 91 | e.p = &curvePoint{} 92 | } 93 | e.p.Neg(a.p) 94 | return e 95 | } 96 | 97 | // Set sets e to a and then returns e. 98 | func (e *G1) Set(a *G1) *G1 { 99 | if e.p == nil { 100 | e.p = &curvePoint{} 101 | } 102 | e.p.Set(a.p) 103 | return e 104 | } 105 | 106 | // Marshal converts e to a byte slice. 107 | func (e *G1) Marshal() []byte { 108 | // Each value is a 256-bit number. 109 | const numBytes = 256 / 8 110 | 111 | if e.p == nil { 112 | e.p = &curvePoint{} 113 | } 114 | 115 | e.p.MakeAffine() 116 | ret := make([]byte, numBytes*2) 117 | if e.p.IsInfinity() { 118 | return ret 119 | } 120 | temp := &gfP{} 121 | 122 | montDecode(temp, &e.p.x) 123 | temp.Marshal(ret) 124 | montDecode(temp, &e.p.y) 125 | temp.Marshal(ret[numBytes:]) 126 | 127 | return ret 128 | } 129 | 130 | // Unmarshal sets e to the result of converting the output of Marshal back into 131 | // a group element and then returns e. 132 | func (e *G1) Unmarshal(m []byte) ([]byte, error) { 133 | // Each value is a 256-bit number. 134 | const numBytes = 256 / 8 135 | 136 | if len(m) < 2*numBytes { 137 | return nil, errors.New("bn256: not enough data") 138 | } 139 | 140 | if e.p == nil { 141 | e.p = &curvePoint{} 142 | } else { 143 | e.p.x, e.p.y = gfP{0}, gfP{0} 144 | } 145 | 146 | e.p.x.Unmarshal(m) 147 | e.p.y.Unmarshal(m[numBytes:]) 148 | montEncode(&e.p.x, &e.p.x) 149 | montEncode(&e.p.y, &e.p.y) 150 | 151 | zero := gfP{0} 152 | if e.p.x == zero && e.p.y == zero { 153 | // This is the point at infinity. 154 | e.p.y = *newGFp(1) 155 | e.p.z = gfP{0} 156 | e.p.t = gfP{0} 157 | } else { 158 | e.p.z = *newGFp(1) 159 | e.p.t = *newGFp(1) 160 | 161 | if !e.p.IsOnCurve() { 162 | return nil, errors.New("bn256: malformed point") 163 | } 164 | } 165 | 166 | return m[2*numBytes:], nil 167 | } 168 | 169 | // G2 is an abstract cyclic group. The zero value is suitable for use as the 170 | // output of an operation, but cannot be used as an input. 171 | type G2 struct { 172 | p *twistPoint 173 | } 174 | 175 | //Gen2 is the generator of G2. 176 | var Gen2 = &G2{twistGen} 177 | 178 | // RandomG2 returns x and g₂ˣ where x is a random, non-zero number read from r. 179 | func RandomG2(r io.Reader) (*big.Int, *G2, error) { 180 | k, err := randomK(r) 181 | if err != nil { 182 | return nil, nil, err 183 | } 184 | 185 | return k, new(G2).ScalarBaseMult(k), nil 186 | } 187 | 188 | func (e *G2) String() string { 189 | return "bn256.G2" + e.p.String() 190 | } 191 | 192 | // ScalarBaseMult sets e to g*k where g is the generator of the group and then 193 | // returns out. 194 | func (e *G2) ScalarBaseMult(k *big.Int) *G2 { 195 | if e.p == nil { 196 | e.p = &twistPoint{} 197 | } 198 | e.p.Mul(twistGen, k) 199 | return e 200 | } 201 | 202 | // ScalarMult sets e to a*k and then returns e. 203 | func (e *G2) ScalarMult(a *G2, k *big.Int) *G2 { 204 | if e.p == nil { 205 | e.p = &twistPoint{} 206 | } 207 | e.p.Mul(a.p, k) 208 | return e 209 | } 210 | 211 | // Add sets e to a+b and then returns e. 212 | func (e *G2) Add(a, b *G2) *G2 { 213 | if e.p == nil { 214 | e.p = &twistPoint{} 215 | } 216 | e.p.Add(a.p, b.p) 217 | return e 218 | } 219 | 220 | // Neg sets e to -a and then returns e. 221 | func (e *G2) Neg(a *G2) *G2 { 222 | if e.p == nil { 223 | e.p = &twistPoint{} 224 | } 225 | e.p.Neg(a.p) 226 | return e 227 | } 228 | 229 | // Set sets e to a and then returns e. 230 | func (e *G2) Set(a *G2) *G2 { 231 | if e.p == nil { 232 | e.p = &twistPoint{} 233 | } 234 | e.p.Set(a.p) 235 | return e 236 | } 237 | 238 | // Marshal converts e into a byte slice. 239 | func (e *G2) Marshal() []byte { 240 | // Each value is a 256-bit number. 241 | const numBytes = 256 / 8 242 | 243 | if e.p == nil { 244 | e.p = &twistPoint{} 245 | } 246 | 247 | e.p.MakeAffine() 248 | if e.p.IsInfinity() { 249 | return make([]byte, 1) 250 | } 251 | 252 | ret := make([]byte, 1+numBytes*4) 253 | ret[0] = 0x01 254 | temp := &gfP{} 255 | 256 | montDecode(temp, &e.p.x.x) 257 | temp.Marshal(ret[1:]) 258 | montDecode(temp, &e.p.x.y) 259 | temp.Marshal(ret[1+numBytes:]) 260 | montDecode(temp, &e.p.y.x) 261 | temp.Marshal(ret[1+2*numBytes:]) 262 | montDecode(temp, &e.p.y.y) 263 | temp.Marshal(ret[1+3*numBytes:]) 264 | 265 | return ret 266 | } 267 | 268 | // Unmarshal sets e to the result of converting the output of Marshal back into 269 | // a group element and then returns e. 270 | func (e *G2) Unmarshal(m []byte) ([]byte, error) { 271 | // Each value is a 256-bit number. 272 | const numBytes = 256 / 8 273 | 274 | if e.p == nil { 275 | e.p = &twistPoint{} 276 | } 277 | 278 | if len(m) > 0 && m[0] == 0x00 { 279 | e.p.SetInfinity() 280 | return m[1:], nil 281 | } else if len(m) > 0 && m[0] != 0x01 { 282 | return nil, errors.New("bn256: malformed point") 283 | } else if len(m) < 1+4*numBytes { 284 | return nil, errors.New("bn256: not enough data") 285 | } 286 | 287 | e.p.x.x.Unmarshal(m[1:]) 288 | e.p.x.y.Unmarshal(m[1+numBytes:]) 289 | e.p.y.x.Unmarshal(m[1+2*numBytes:]) 290 | e.p.y.y.Unmarshal(m[1+3*numBytes:]) 291 | montEncode(&e.p.x.x, &e.p.x.x) 292 | montEncode(&e.p.x.y, &e.p.x.y) 293 | montEncode(&e.p.y.x, &e.p.y.x) 294 | montEncode(&e.p.y.y, &e.p.y.y) 295 | 296 | if e.p.x.IsZero() && e.p.y.IsZero() { 297 | // This is the point at infinity. 298 | e.p.y.SetOne() 299 | e.p.z.SetZero() 300 | e.p.t.SetZero() 301 | } else { 302 | e.p.z.SetOne() 303 | e.p.t.SetOne() 304 | 305 | if !e.p.IsOnCurve() { 306 | return nil, errors.New("bn256: malformed point") 307 | } 308 | } 309 | 310 | return m[1+4*numBytes:], nil 311 | } 312 | 313 | // GT is an abstract cyclic group. The zero value is suitable for use as the 314 | // output of an operation, but cannot be used as an input. 315 | type GT struct { 316 | p *gfP12 317 | } 318 | 319 | // RandomGT returns x and e(g₁, g₂)ˣ where x is a random, non-zero number read 320 | // from r. 321 | func RandomGT(r io.Reader) (*big.Int, *GT, error) { 322 | k, err := randomK(r) 323 | if err != nil { 324 | return nil, nil, err 325 | } 326 | 327 | return k, new(GT).ScalarBaseMult(k), nil 328 | } 329 | 330 | // Pair calculates an Optimal Ate pairing. 331 | func Pair(g1 *G1, g2 *G2) *GT { 332 | g := optimalAte(g2.p, g1.p) 333 | return >{g} 334 | } 335 | 336 | // Miller applies Miller's algorithm, which is a bilinear function from the 337 | // source groups to F_p^12. Miller(g1, g2).Finalize() is equivalent to Pair(g1, 338 | // g2). 339 | func Miller(g1 *G1, g2 *G2) *GT { 340 | return >{miller(g2.p, g1.p)} 341 | } 342 | 343 | func (g *GT) String() string { 344 | der := montDecodeGfp12(*g.p) 345 | return "bn256.GT" + der.String() 346 | } 347 | 348 | // ScalarBaseMult sets e to g*k where g is the generator of the group and then 349 | // returns out. 350 | func (e *GT) ScalarBaseMult(k *big.Int) *GT { 351 | if e.p == nil { 352 | e.p = &gfP12{} 353 | } 354 | e.p.Exp(gfP12Gen, k) 355 | return e 356 | } 357 | 358 | // ScalarMult sets e to a*k and then returns e. 359 | func (e *GT) ScalarMult(a *GT, k *big.Int) *GT { 360 | if e.p == nil { 361 | e.p = &gfP12{} 362 | } 363 | e.p.Exp(a.p, k) 364 | return e 365 | } 366 | 367 | // Add sets e to a+b and then returns e. 368 | func (e *GT) Add(a, b *GT) *GT { 369 | if e.p == nil { 370 | e.p = &gfP12{} 371 | } 372 | e.p.Mul(a.p, b.p) 373 | return e 374 | } 375 | 376 | // Neg sets e to -a and then returns e. 377 | func (e *GT) Neg(a *GT) *GT { 378 | if e.p == nil { 379 | e.p = &gfP12{} 380 | } 381 | e.p.Conjugate(a.p) 382 | return e 383 | } 384 | 385 | // Set sets e to a and then returns e. 386 | func (e *GT) Set(a *GT) *GT { 387 | if e.p == nil { 388 | e.p = &gfP12{} 389 | } 390 | e.p.Set(a.p) 391 | return e 392 | } 393 | 394 | // Finalize is a linear function from F_p^12 to GT. 395 | func (e *GT) Finalize() *GT { 396 | ret := finalExponentiation(e.p) 397 | e.p.Set(ret) 398 | return e 399 | } 400 | 401 | // Marshal converts e into a byte slice. 402 | func (e *GT) Marshal() []byte { 403 | // Each value is a 256-bit number. 404 | const numBytes = 256 / 8 405 | 406 | if e.p == nil { 407 | e.p = &gfP12{} 408 | e.p.SetOne() 409 | } 410 | 411 | ret := make([]byte, numBytes*12) 412 | temp := &gfP{} 413 | 414 | montDecode(temp, &e.p.x.x.x) 415 | temp.Marshal(ret) 416 | montDecode(temp, &e.p.x.x.y) 417 | temp.Marshal(ret[numBytes:]) 418 | montDecode(temp, &e.p.x.y.x) 419 | temp.Marshal(ret[2*numBytes:]) 420 | montDecode(temp, &e.p.x.y.y) 421 | temp.Marshal(ret[3*numBytes:]) 422 | montDecode(temp, &e.p.x.z.x) 423 | temp.Marshal(ret[4*numBytes:]) 424 | montDecode(temp, &e.p.x.z.y) 425 | temp.Marshal(ret[5*numBytes:]) 426 | montDecode(temp, &e.p.y.x.x) 427 | temp.Marshal(ret[6*numBytes:]) 428 | montDecode(temp, &e.p.y.x.y) 429 | temp.Marshal(ret[7*numBytes:]) 430 | montDecode(temp, &e.p.y.y.x) 431 | temp.Marshal(ret[8*numBytes:]) 432 | montDecode(temp, &e.p.y.y.y) 433 | temp.Marshal(ret[9*numBytes:]) 434 | montDecode(temp, &e.p.y.z.x) 435 | temp.Marshal(ret[10*numBytes:]) 436 | montDecode(temp, &e.p.y.z.y) 437 | temp.Marshal(ret[11*numBytes:]) 438 | 439 | return ret 440 | } 441 | 442 | // Unmarshal sets e to the result of converting the output of Marshal back into 443 | // a group element and then returns e. 444 | func (e *GT) Unmarshal(m []byte) ([]byte, error) { 445 | // Each value is a 256-bit number. 446 | const numBytes = 256 / 8 447 | 448 | if len(m) < 12*numBytes { 449 | return nil, errors.New("bn256: not enough data") 450 | } 451 | 452 | if e.p == nil { 453 | e.p = &gfP12{} 454 | } 455 | 456 | e.p.x.x.x.Unmarshal(m) 457 | e.p.x.x.y.Unmarshal(m[numBytes:]) 458 | e.p.x.y.x.Unmarshal(m[2*numBytes:]) 459 | e.p.x.y.y.Unmarshal(m[3*numBytes:]) 460 | e.p.x.z.x.Unmarshal(m[4*numBytes:]) 461 | e.p.x.z.y.Unmarshal(m[5*numBytes:]) 462 | e.p.y.x.x.Unmarshal(m[6*numBytes:]) 463 | e.p.y.x.y.Unmarshal(m[7*numBytes:]) 464 | e.p.y.y.x.Unmarshal(m[8*numBytes:]) 465 | e.p.y.y.y.Unmarshal(m[9*numBytes:]) 466 | e.p.y.z.x.Unmarshal(m[10*numBytes:]) 467 | e.p.y.z.y.Unmarshal(m[11*numBytes:]) 468 | montEncode(&e.p.x.x.x, &e.p.x.x.x) 469 | montEncode(&e.p.x.x.y, &e.p.x.x.y) 470 | montEncode(&e.p.x.y.x, &e.p.x.y.x) 471 | montEncode(&e.p.x.y.y, &e.p.x.y.y) 472 | montEncode(&e.p.x.z.x, &e.p.x.z.x) 473 | montEncode(&e.p.x.z.y, &e.p.x.z.y) 474 | montEncode(&e.p.y.x.x, &e.p.y.x.x) 475 | montEncode(&e.p.y.x.y, &e.p.y.x.y) 476 | montEncode(&e.p.y.y.x, &e.p.y.y.x) 477 | montEncode(&e.p.y.y.y, &e.p.y.y.y) 478 | montEncode(&e.p.y.z.x, &e.p.y.z.x) 479 | montEncode(&e.p.y.z.y, &e.p.y.z.y) 480 | 481 | return m[12*numBytes:], nil 482 | } 483 | -------------------------------------------------------------------------------- /sm/sm4/const.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 cetc-30. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package sm4 6 | 7 | type cryptMode int 8 | 9 | const BlockSize = 16 10 | 11 | const ( 12 | ENC cryptMode = iota 13 | DEC 14 | ) 15 | 16 | //sbox in sm4 17 | var sbox = [16][16]byte{ 18 | {0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05}, 19 | {0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99}, 20 | {0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62}, 21 | {0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6}, 22 | {0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8}, 23 | {0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35}, 24 | {0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87}, 25 | {0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e}, 26 | {0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1}, 27 | {0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3}, 28 | {0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f}, 29 | {0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51}, 30 | {0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8}, 31 | {0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0}, 32 | {0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84}, 33 | {0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48}, 34 | } 35 | 36 | //FK constants 37 | var fk = [4]uint32{0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc} 38 | 39 | //CK constants 40 | var ck = [32]uint32{ 41 | 0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269, 42 | 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9, 43 | 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249, 44 | 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9, 45 | 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229, 46 | 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299, 47 | 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209, 48 | 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279, 49 | } 50 | 51 | //For detail, see tojgm algorithm as code in https://github.com/tjfoc/gmsm/sm4/sm4.go. 52 | var sbox0 = [256]uint32{ 53 | 0xd55b5b8e, 0x924242d0, 0xeaa7a74d, 0xfdfbfb06, 0xcf3333fc, 0xe2878765, 0x3df4f4c9, 0xb5dede6b, 0x1658584e, 0xb4dada6e, 0x14505044, 0xc10b0bca, 0x28a0a088, 0xf8efef17, 0x2cb0b09c, 0x05141411, 54 | 0x2bacac87, 0x669d9dfb, 0x986a6af2, 0x77d9d9ae, 0x2aa8a882, 0xbcfafa46, 0x04101014, 0xc00f0fcf, 0xa8aaaa02, 0x45111154, 0x134c4c5f, 0x269898be, 0x4825256d, 0x841a1a9e, 0x0618181e, 0x9b6666fd, 55 | 0x9e7272ec, 0x4309094a, 0x51414110, 0xf7d3d324, 0x934646d5, 0xecbfbf53, 0x9a6262f8, 0x7be9e992, 0x33ccccff, 0x55515104, 0x0b2c2c27, 0x420d0d4f, 0xeeb7b759, 0xcc3f3ff3, 0xaeb2b21c, 0x638989ea, 56 | 0xe7939374, 0xb1cece7f, 0x1c70706c, 0xaba6a60d, 0xca2727ed, 0x08202028, 0xeba3a348, 0x975656c1, 0x82020280, 0xdc7f7fa3, 0x965252c4, 0xf9ebeb12, 0x74d5d5a1, 0x8d3e3eb3, 0x3ffcfcc3, 0xa49a9a3e, 57 | 0x461d1d5b, 0x071c1c1b, 0xa59e9e3b, 0xfff3f30c, 0xf0cfcf3f, 0x72cdcdbf, 0x175c5c4b, 0xb8eaea52, 0x810e0e8f, 0x5865653d, 0x3cf0f0cc, 0x1964647d, 0xe59b9b7e, 0x87161691, 0x4e3d3d73, 0xaaa2a208, 58 | 0x69a1a1c8, 0x6aadadc7, 0x83060685, 0xb0caca7a, 0x70c5c5b5, 0x659191f4, 0xd96b6bb2, 0x892e2ea7, 0xfbe3e318, 0xe8afaf47, 0x0f3c3c33, 0x4a2d2d67, 0x71c1c1b0, 0x5759590e, 0x9f7676e9, 0x35d4d4e1, 59 | 0x1e787866, 0x249090b4, 0x0e383836, 0x5f797926, 0x628d8def, 0x59616138, 0xd2474795, 0xa08a8a2a, 0x259494b1, 0x228888aa, 0x7df1f18c, 0x3bececd7, 0x01040405, 0x218484a5, 0x79e1e198, 0x851e1e9b, 60 | 0xd7535384, 0x00000000, 0x4719195e, 0x565d5d0b, 0x9d7e7ee3, 0xd04f4f9f, 0x279c9cbb, 0x5349491a, 0x4d31317c, 0x36d8d8ee, 0x0208080a, 0xe49f9f7b, 0xa2828220, 0xc71313d4, 0xcb2323e8, 0x9c7a7ae6, 61 | 0xe9abab42, 0xbdfefe43, 0x882a2aa2, 0xd14b4b9a, 0x41010140, 0xc41f1fdb, 0x38e0e0d8, 0xb7d6d661, 0xa18e8e2f, 0xf4dfdf2b, 0xf1cbcb3a, 0xcd3b3bf6, 0xfae7e71d, 0x608585e5, 0x15545441, 0xa3868625, 62 | 0xe3838360, 0xacbaba16, 0x5c757529, 0xa6929234, 0x996e6ef7, 0x34d0d0e4, 0x1a686872, 0x54555501, 0xafb6b619, 0x914e4edf, 0x32c8c8fa, 0x30c0c0f0, 0xf6d7d721, 0x8e3232bc, 0xb3c6c675, 0xe08f8f6f, 63 | 0x1d747469, 0xf5dbdb2e, 0xe18b8b6a, 0x2eb8b896, 0x800a0a8a, 0x679999fe, 0xc92b2be2, 0x618181e0, 0xc30303c0, 0x29a4a48d, 0x238c8caf, 0xa9aeae07, 0x0d343439, 0x524d4d1f, 0x4f393976, 0x6ebdbdd3, 64 | 0xd6575781, 0xd86f6fb7, 0x37dcdceb, 0x44151551, 0xdd7b7ba6, 0xfef7f709, 0x8c3a3ab6, 0x2fbcbc93, 0x030c0c0f, 0xfcffff03, 0x6ba9a9c2, 0x73c9c9ba, 0x6cb5b5d9, 0x6db1b1dc, 0x5a6d6d37, 0x50454515, 65 | 0x8f3636b9, 0x1b6c6c77, 0xadbebe13, 0x904a4ada, 0xb9eeee57, 0xde7777a9, 0xbef2f24c, 0x7efdfd83, 0x11444455, 0xda6767bd, 0x5d71712c, 0x40050545, 0x1f7c7c63, 0x10404050, 0x5b696932, 0xdb6363b8, 66 | 0x0a282822, 0xc20707c5, 0x31c4c4f5, 0x8a2222a8, 0xa7969631, 0xce3737f9, 0x7aeded97, 0xbff6f649, 0x2db4b499, 0x75d1d1a4, 0xd3434390, 0x1248485a, 0xbae2e258, 0xe6979771, 0xb6d2d264, 0xb2c2c270, 67 | 0x8b2626ad, 0x68a5a5cd, 0x955e5ecb, 0x4b292962, 0x0c30303c, 0x945a5ace, 0x76ddddab, 0x7ff9f986, 0x649595f1, 0xbbe6e65d, 0xf2c7c735, 0x0924242d, 0xc61717d1, 0x6fb9b9d6, 0xc51b1bde, 0x86121294, 68 | 0x18606078, 0xf3c3c330, 0x7cf5f589, 0xefb3b35c, 0x3ae8e8d2, 0xdf7373ac, 0x4c353579, 0x208080a0, 0x78e5e59d, 0xedbbbb56, 0x5e7d7d23, 0x3ef8f8c6, 0xd45f5f8b, 0xc82f2fe7, 0x39e4e4dd, 0x49212168, 69 | } 70 | 71 | var sbox1 = [256]uint32{ 72 | 0x5b5b8ed5, 0x4242d092, 0xa7a74dea, 0xfbfb06fd, 0x3333fccf, 0x878765e2, 0xf4f4c93d, 0xdede6bb5, 0x58584e16, 0xdada6eb4, 0x50504414, 0x0b0bcac1, 0xa0a08828, 0xefef17f8, 0xb0b09c2c, 0x14141105, 73 | 0xacac872b, 0x9d9dfb66, 0x6a6af298, 0xd9d9ae77, 0xa8a8822a, 0xfafa46bc, 0x10101404, 0x0f0fcfc0, 0xaaaa02a8, 0x11115445, 0x4c4c5f13, 0x9898be26, 0x25256d48, 0x1a1a9e84, 0x18181e06, 0x6666fd9b, 74 | 0x7272ec9e, 0x09094a43, 0x41411051, 0xd3d324f7, 0x4646d593, 0xbfbf53ec, 0x6262f89a, 0xe9e9927b, 0xccccff33, 0x51510455, 0x2c2c270b, 0x0d0d4f42, 0xb7b759ee, 0x3f3ff3cc, 0xb2b21cae, 0x8989ea63, 75 | 0x939374e7, 0xcece7fb1, 0x70706c1c, 0xa6a60dab, 0x2727edca, 0x20202808, 0xa3a348eb, 0x5656c197, 0x02028082, 0x7f7fa3dc, 0x5252c496, 0xebeb12f9, 0xd5d5a174, 0x3e3eb38d, 0xfcfcc33f, 0x9a9a3ea4, 76 | 0x1d1d5b46, 0x1c1c1b07, 0x9e9e3ba5, 0xf3f30cff, 0xcfcf3ff0, 0xcdcdbf72, 0x5c5c4b17, 0xeaea52b8, 0x0e0e8f81, 0x65653d58, 0xf0f0cc3c, 0x64647d19, 0x9b9b7ee5, 0x16169187, 0x3d3d734e, 0xa2a208aa, 77 | 0xa1a1c869, 0xadadc76a, 0x06068583, 0xcaca7ab0, 0xc5c5b570, 0x9191f465, 0x6b6bb2d9, 0x2e2ea789, 0xe3e318fb, 0xafaf47e8, 0x3c3c330f, 0x2d2d674a, 0xc1c1b071, 0x59590e57, 0x7676e99f, 0xd4d4e135, 78 | 0x7878661e, 0x9090b424, 0x3838360e, 0x7979265f, 0x8d8def62, 0x61613859, 0x474795d2, 0x8a8a2aa0, 0x9494b125, 0x8888aa22, 0xf1f18c7d, 0xececd73b, 0x04040501, 0x8484a521, 0xe1e19879, 0x1e1e9b85, 79 | 0x535384d7, 0x00000000, 0x19195e47, 0x5d5d0b56, 0x7e7ee39d, 0x4f4f9fd0, 0x9c9cbb27, 0x49491a53, 0x31317c4d, 0xd8d8ee36, 0x08080a02, 0x9f9f7be4, 0x828220a2, 0x1313d4c7, 0x2323e8cb, 0x7a7ae69c, 80 | 0xabab42e9, 0xfefe43bd, 0x2a2aa288, 0x4b4b9ad1, 0x01014041, 0x1f1fdbc4, 0xe0e0d838, 0xd6d661b7, 0x8e8e2fa1, 0xdfdf2bf4, 0xcbcb3af1, 0x3b3bf6cd, 0xe7e71dfa, 0x8585e560, 0x54544115, 0x868625a3, 81 | 0x838360e3, 0xbaba16ac, 0x7575295c, 0x929234a6, 0x6e6ef799, 0xd0d0e434, 0x6868721a, 0x55550154, 0xb6b619af, 0x4e4edf91, 0xc8c8fa32, 0xc0c0f030, 0xd7d721f6, 0x3232bc8e, 0xc6c675b3, 0x8f8f6fe0, 82 | 0x7474691d, 0xdbdb2ef5, 0x8b8b6ae1, 0xb8b8962e, 0x0a0a8a80, 0x9999fe67, 0x2b2be2c9, 0x8181e061, 0x0303c0c3, 0xa4a48d29, 0x8c8caf23, 0xaeae07a9, 0x3434390d, 0x4d4d1f52, 0x3939764f, 0xbdbdd36e, 83 | 0x575781d6, 0x6f6fb7d8, 0xdcdceb37, 0x15155144, 0x7b7ba6dd, 0xf7f709fe, 0x3a3ab68c, 0xbcbc932f, 0x0c0c0f03, 0xffff03fc, 0xa9a9c26b, 0xc9c9ba73, 0xb5b5d96c, 0xb1b1dc6d, 0x6d6d375a, 0x45451550, 84 | 0x3636b98f, 0x6c6c771b, 0xbebe13ad, 0x4a4ada90, 0xeeee57b9, 0x7777a9de, 0xf2f24cbe, 0xfdfd837e, 0x44445511, 0x6767bdda, 0x71712c5d, 0x05054540, 0x7c7c631f, 0x40405010, 0x6969325b, 0x6363b8db, 85 | 0x2828220a, 0x0707c5c2, 0xc4c4f531, 0x2222a88a, 0x969631a7, 0x3737f9ce, 0xeded977a, 0xf6f649bf, 0xb4b4992d, 0xd1d1a475, 0x434390d3, 0x48485a12, 0xe2e258ba, 0x979771e6, 0xd2d264b6, 0xc2c270b2, 86 | 0x2626ad8b, 0xa5a5cd68, 0x5e5ecb95, 0x2929624b, 0x30303c0c, 0x5a5ace94, 0xddddab76, 0xf9f9867f, 0x9595f164, 0xe6e65dbb, 0xc7c735f2, 0x24242d09, 0x1717d1c6, 0xb9b9d66f, 0x1b1bdec5, 0x12129486, 87 | 0x60607818, 0xc3c330f3, 0xf5f5897c, 0xb3b35cef, 0xe8e8d23a, 0x7373acdf, 0x3535794c, 0x8080a020, 0xe5e59d78, 0xbbbb56ed, 0x7d7d235e, 0xf8f8c63e, 0x5f5f8bd4, 0x2f2fe7c8, 0xe4e4dd39, 0x21216849, 88 | } 89 | 90 | var sbox2 = [256]uint32{ 91 | 0x5b8ed55b, 0x42d09242, 0xa74deaa7, 0xfb06fdfb, 0x33fccf33, 0x8765e287, 0xf4c93df4, 0xde6bb5de, 0x584e1658, 0xda6eb4da, 0x50441450, 0x0bcac10b, 0xa08828a0, 0xef17f8ef, 0xb09c2cb0, 0x14110514, 92 | 0xac872bac, 0x9dfb669d, 0x6af2986a, 0xd9ae77d9, 0xa8822aa8, 0xfa46bcfa, 0x10140410, 0x0fcfc00f, 0xaa02a8aa, 0x11544511, 0x4c5f134c, 0x98be2698, 0x256d4825, 0x1a9e841a, 0x181e0618, 0x66fd9b66, 93 | 0x72ec9e72, 0x094a4309, 0x41105141, 0xd324f7d3, 0x46d59346, 0xbf53ecbf, 0x62f89a62, 0xe9927be9, 0xccff33cc, 0x51045551, 0x2c270b2c, 0x0d4f420d, 0xb759eeb7, 0x3ff3cc3f, 0xb21caeb2, 0x89ea6389, 94 | 0x9374e793, 0xce7fb1ce, 0x706c1c70, 0xa60daba6, 0x27edca27, 0x20280820, 0xa348eba3, 0x56c19756, 0x02808202, 0x7fa3dc7f, 0x52c49652, 0xeb12f9eb, 0xd5a174d5, 0x3eb38d3e, 0xfcc33ffc, 0x9a3ea49a, 95 | 0x1d5b461d, 0x1c1b071c, 0x9e3ba59e, 0xf30cfff3, 0xcf3ff0cf, 0xcdbf72cd, 0x5c4b175c, 0xea52b8ea, 0x0e8f810e, 0x653d5865, 0xf0cc3cf0, 0x647d1964, 0x9b7ee59b, 0x16918716, 0x3d734e3d, 0xa208aaa2, 96 | 0xa1c869a1, 0xadc76aad, 0x06858306, 0xca7ab0ca, 0xc5b570c5, 0x91f46591, 0x6bb2d96b, 0x2ea7892e, 0xe318fbe3, 0xaf47e8af, 0x3c330f3c, 0x2d674a2d, 0xc1b071c1, 0x590e5759, 0x76e99f76, 0xd4e135d4, 97 | 0x78661e78, 0x90b42490, 0x38360e38, 0x79265f79, 0x8def628d, 0x61385961, 0x4795d247, 0x8a2aa08a, 0x94b12594, 0x88aa2288, 0xf18c7df1, 0xecd73bec, 0x04050104, 0x84a52184, 0xe19879e1, 0x1e9b851e, 98 | 0x5384d753, 0x00000000, 0x195e4719, 0x5d0b565d, 0x7ee39d7e, 0x4f9fd04f, 0x9cbb279c, 0x491a5349, 0x317c4d31, 0xd8ee36d8, 0x080a0208, 0x9f7be49f, 0x8220a282, 0x13d4c713, 0x23e8cb23, 0x7ae69c7a, 99 | 0xab42e9ab, 0xfe43bdfe, 0x2aa2882a, 0x4b9ad14b, 0x01404101, 0x1fdbc41f, 0xe0d838e0, 0xd661b7d6, 0x8e2fa18e, 0xdf2bf4df, 0xcb3af1cb, 0x3bf6cd3b, 0xe71dfae7, 0x85e56085, 0x54411554, 0x8625a386, 100 | 0x8360e383, 0xba16acba, 0x75295c75, 0x9234a692, 0x6ef7996e, 0xd0e434d0, 0x68721a68, 0x55015455, 0xb619afb6, 0x4edf914e, 0xc8fa32c8, 0xc0f030c0, 0xd721f6d7, 0x32bc8e32, 0xc675b3c6, 0x8f6fe08f, 101 | 0x74691d74, 0xdb2ef5db, 0x8b6ae18b, 0xb8962eb8, 0x0a8a800a, 0x99fe6799, 0x2be2c92b, 0x81e06181, 0x03c0c303, 0xa48d29a4, 0x8caf238c, 0xae07a9ae, 0x34390d34, 0x4d1f524d, 0x39764f39, 0xbdd36ebd, 102 | 0x5781d657, 0x6fb7d86f, 0xdceb37dc, 0x15514415, 0x7ba6dd7b, 0xf709fef7, 0x3ab68c3a, 0xbc932fbc, 0x0c0f030c, 0xff03fcff, 0xa9c26ba9, 0xc9ba73c9, 0xb5d96cb5, 0xb1dc6db1, 0x6d375a6d, 0x45155045, 103 | 0x36b98f36, 0x6c771b6c, 0xbe13adbe, 0x4ada904a, 0xee57b9ee, 0x77a9de77, 0xf24cbef2, 0xfd837efd, 0x44551144, 0x67bdda67, 0x712c5d71, 0x05454005, 0x7c631f7c, 0x40501040, 0x69325b69, 0x63b8db63, 104 | 0x28220a28, 0x07c5c207, 0xc4f531c4, 0x22a88a22, 0x9631a796, 0x37f9ce37, 0xed977aed, 0xf649bff6, 0xb4992db4, 0xd1a475d1, 0x4390d343, 0x485a1248, 0xe258bae2, 0x9771e697, 0xd264b6d2, 0xc270b2c2, 105 | 0x26ad8b26, 0xa5cd68a5, 0x5ecb955e, 0x29624b29, 0x303c0c30, 0x5ace945a, 0xddab76dd, 0xf9867ff9, 0x95f16495, 0xe65dbbe6, 0xc735f2c7, 0x242d0924, 0x17d1c617, 0xb9d66fb9, 0x1bdec51b, 0x12948612, 106 | 0x60781860, 0xc330f3c3, 0xf5897cf5, 0xb35cefb3, 0xe8d23ae8, 0x73acdf73, 0x35794c35, 0x80a02080, 0xe59d78e5, 0xbb56edbb, 0x7d235e7d, 0xf8c63ef8, 0x5f8bd45f, 0x2fe7c82f, 0xe4dd39e4, 0x21684921, 107 | } 108 | 109 | var sbox3 = [256]uint32{ 110 | 0x8ed55b5b, 0xd0924242, 0x4deaa7a7, 0x06fdfbfb, 0xfccf3333, 0x65e28787, 0xc93df4f4, 0x6bb5dede, 0x4e165858, 0x6eb4dada, 0x44145050, 0xcac10b0b, 0x8828a0a0, 0x17f8efef, 0x9c2cb0b0, 0x11051414, 111 | 0x872bacac, 0xfb669d9d, 0xf2986a6a, 0xae77d9d9, 0x822aa8a8, 0x46bcfafa, 0x14041010, 0xcfc00f0f, 0x02a8aaaa, 0x54451111, 0x5f134c4c, 0xbe269898, 0x6d482525, 0x9e841a1a, 0x1e061818, 0xfd9b6666, 112 | 0xec9e7272, 0x4a430909, 0x10514141, 0x24f7d3d3, 0xd5934646, 0x53ecbfbf, 0xf89a6262, 0x927be9e9, 0xff33cccc, 0x04555151, 0x270b2c2c, 0x4f420d0d, 0x59eeb7b7, 0xf3cc3f3f, 0x1caeb2b2, 0xea638989, 113 | 0x74e79393, 0x7fb1cece, 0x6c1c7070, 0x0daba6a6, 0xedca2727, 0x28082020, 0x48eba3a3, 0xc1975656, 0x80820202, 0xa3dc7f7f, 0xc4965252, 0x12f9ebeb, 0xa174d5d5, 0xb38d3e3e, 0xc33ffcfc, 0x3ea49a9a, 114 | 0x5b461d1d, 0x1b071c1c, 0x3ba59e9e, 0x0cfff3f3, 0x3ff0cfcf, 0xbf72cdcd, 0x4b175c5c, 0x52b8eaea, 0x8f810e0e, 0x3d586565, 0xcc3cf0f0, 0x7d196464, 0x7ee59b9b, 0x91871616, 0x734e3d3d, 0x08aaa2a2, 115 | 0xc869a1a1, 0xc76aadad, 0x85830606, 0x7ab0caca, 0xb570c5c5, 0xf4659191, 0xb2d96b6b, 0xa7892e2e, 0x18fbe3e3, 0x47e8afaf, 0x330f3c3c, 0x674a2d2d, 0xb071c1c1, 0x0e575959, 0xe99f7676, 0xe135d4d4, 116 | 0x661e7878, 0xb4249090, 0x360e3838, 0x265f7979, 0xef628d8d, 0x38596161, 0x95d24747, 0x2aa08a8a, 0xb1259494, 0xaa228888, 0x8c7df1f1, 0xd73becec, 0x05010404, 0xa5218484, 0x9879e1e1, 0x9b851e1e, 117 | 0x84d75353, 0x00000000, 0x5e471919, 0x0b565d5d, 0xe39d7e7e, 0x9fd04f4f, 0xbb279c9c, 0x1a534949, 0x7c4d3131, 0xee36d8d8, 0x0a020808, 0x7be49f9f, 0x20a28282, 0xd4c71313, 0xe8cb2323, 0xe69c7a7a, 118 | 0x42e9abab, 0x43bdfefe, 0xa2882a2a, 0x9ad14b4b, 0x40410101, 0xdbc41f1f, 0xd838e0e0, 0x61b7d6d6, 0x2fa18e8e, 0x2bf4dfdf, 0x3af1cbcb, 0xf6cd3b3b, 0x1dfae7e7, 0xe5608585, 0x41155454, 0x25a38686, 119 | 0x60e38383, 0x16acbaba, 0x295c7575, 0x34a69292, 0xf7996e6e, 0xe434d0d0, 0x721a6868, 0x01545555, 0x19afb6b6, 0xdf914e4e, 0xfa32c8c8, 0xf030c0c0, 0x21f6d7d7, 0xbc8e3232, 0x75b3c6c6, 0x6fe08f8f, 120 | 0x691d7474, 0x2ef5dbdb, 0x6ae18b8b, 0x962eb8b8, 0x8a800a0a, 0xfe679999, 0xe2c92b2b, 0xe0618181, 0xc0c30303, 0x8d29a4a4, 0xaf238c8c, 0x07a9aeae, 0x390d3434, 0x1f524d4d, 0x764f3939, 0xd36ebdbd, 121 | 0x81d65757, 0xb7d86f6f, 0xeb37dcdc, 0x51441515, 0xa6dd7b7b, 0x09fef7f7, 0xb68c3a3a, 0x932fbcbc, 0x0f030c0c, 0x03fcffff, 0xc26ba9a9, 0xba73c9c9, 0xd96cb5b5, 0xdc6db1b1, 0x375a6d6d, 0x15504545, 122 | 0xb98f3636, 0x771b6c6c, 0x13adbebe, 0xda904a4a, 0x57b9eeee, 0xa9de7777, 0x4cbef2f2, 0x837efdfd, 0x55114444, 0xbdda6767, 0x2c5d7171, 0x45400505, 0x631f7c7c, 0x50104040, 0x325b6969, 0xb8db6363, 123 | 0x220a2828, 0xc5c20707, 0xf531c4c4, 0xa88a2222, 0x31a79696, 0xf9ce3737, 0x977aeded, 0x49bff6f6, 0x992db4b4, 0xa475d1d1, 0x90d34343, 0x5a124848, 0x58bae2e2, 0x71e69797, 0x64b6d2d2, 0x70b2c2c2, 124 | 0xad8b2626, 0xcd68a5a5, 0xcb955e5e, 0x624b2929, 0x3c0c3030, 0xce945a5a, 0xab76dddd, 0x867ff9f9, 0xf1649595, 0x5dbbe6e6, 0x35f2c7c7, 0x2d092424, 0xd1c61717, 0xd66fb9b9, 0xdec51b1b, 0x94861212, 125 | 0x78186060, 0x30f3c3c3, 0x897cf5f5, 0x5cefb3b3, 0xd23ae8e8, 0xacdf7373, 0x794c3535, 0xa0208080, 0x9d78e5e5, 0x56edbbbb, 0x235e7d7d, 0xc63ef8f8, 0x8bd45f5f, 0xe7c82f2f, 0xdd39e4e4, 0x68492121, 126 | } 127 | --------------------------------------------------------------------------------