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 err = rsa.ErrDecryption 92 return 93 } 94 if priv.Pk.N.Sign() == 0 { 95 return nil, rsa.ErrDecryption 96 } 97 98 var ir *big.Int 99 if random != nil { 100 // Blinding enabled. Blinding involves multiplying c by r^e. 101 // Then the decryption operation performs (m^e * r^e)^d mod n 102 // which equals mr mod n. The factor of r can then be removed 103 // by multiplying by the multiplicative inverse of r. 104 105 var r *big.Int 106 ir = new(big.Int) 107 for { 108 r, err = rand.Int(random, priv.Pk.N) 109 if err != nil { 110 return 111 } 112 if r.Cmp(bigZero) == 0 { 113 r = bigOne 114 } 115 ok := ir.ModInverse(r, priv.Pk.N) 116 if ok != nil { 117 break 118 } 119 } 120 rpowe := new(big.Int).Exp(r, priv.Pk.E, priv.Pk.N) // N != 0 121 cCopy := new(big.Int).Set(c) 122 cCopy.Mul(cCopy, rpowe) 123 cCopy.Mod(cCopy, priv.Pk.N) 124 c = cCopy 125 } 126 127 m = new(big.Int).Exp(c, priv.D, priv.Pk.N) 128 129 if ir != nil { 130 // Unblind. 131 m.Mul(m, ir) 132 m.Mod(m, priv.Pk.N) 133 } 134 135 return m, nil 136 } 137