github.com/cloudflare/circl@v1.5.0/blindsign/blindrsa/internal/common/rsa.go (about) 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 29 package common 30 31 import ( 32 "crypto/rand" 33 "crypto/rsa" 34 "hash" 35 "io" 36 "math/big" 37 38 "github.com/cloudflare/circl/blindsign/blindrsa/internal/keys" 39 ) 40 41 var ( 42 bigZero = big.NewInt(0) 43 bigOne = big.NewInt(1) 44 ) 45 46 // incCounter increments a four byte, big-endian counter. 47 func incCounter(c *[4]byte) { 48 if c[3]++; c[3] != 0 { 49 return 50 } 51 if c[2]++; c[2] != 0 { 52 return 53 } 54 if c[1]++; c[1] != 0 { 55 return 56 } 57 c[0]++ 58 } 59 60 // mgf1XOR XORs the bytes in out with a mask generated using the MGF1 function 61 // specified in PKCS #1 v2.1. 62 func mgf1XOR(out []byte, hash hash.Hash, seed []byte) { 63 var counter [4]byte 64 var digest []byte 65 66 done := 0 67 for done < len(out) { 68 hash.Write(seed) 69 hash.Write(counter[0:4]) 70 digest = hash.Sum(digest[:0]) 71 hash.Reset() 72 73 for i := 0; i < len(digest) && done < len(out); i++ { 74 out[done] ^= digest[i] 75 done++ 76 } 77 incCounter(&counter) 78 } 79 } 80 81 func encrypt(c *big.Int, N *big.Int, e *big.Int, m *big.Int) *big.Int { 82 c.Exp(m, e, N) 83 return c 84 } 85 86 // decrypt performs an RSA decryption, resulting in a plaintext integer. If a 87 // random source is given, RSA blinding is used. 88 func decrypt(random io.Reader, priv *keys.BigPrivateKey, c *big.Int) (m *big.Int, err error) { 89 // TODO(agl): can we get away with reusing blinds? 90 if c.Cmp(priv.Pk.N) > 0 { 91 return nil, rsa.ErrDecryption 92 } 93 if priv.Pk.N.Sign() == 0 { 94 return nil, rsa.ErrDecryption 95 } 96 97 var ir *big.Int 98 if random != nil { 99 // Blinding enabled. Blinding involves multiplying c by r^e. 100 // Then the decryption operation performs (m^e * r^e)^d mod n 101 // which equals mr mod n. The factor of r can then be removed 102 // by multiplying by the multiplicative inverse of r. 103 104 var r *big.Int 105 ir = new(big.Int) 106 for { 107 r, err = rand.Int(random, priv.Pk.N) 108 if err != nil { 109 return nil, err 110 } 111 if r.Cmp(bigZero) == 0 { 112 r = bigOne 113 } 114 ok := ir.ModInverse(r, priv.Pk.N) 115 if ok != nil { 116 break 117 } 118 } 119 rpowe := new(big.Int).Exp(r, priv.Pk.E, priv.Pk.N) // N != 0 120 cCopy := new(big.Int).Set(c) 121 cCopy.Mul(cCopy, rpowe) 122 cCopy.Mod(cCopy, priv.Pk.N) 123 c = cCopy 124 } 125 126 m = new(big.Int).Exp(c, priv.D, priv.Pk.N) 127 128 if ir != nil { 129 // Unblind. 130 m.Mul(m, ir) 131 m.Mod(m, priv.Pk.N) 132 } 133 134 return m, nil 135 }