init: v1.0.0

This commit is contained in:
yaole
2026-05-27 23:03:00 +08:00
commit 8d97f750eb
466 changed files with 80067 additions and 0 deletions
+113
View File
@@ -0,0 +1,113 @@
//go:build !gmp
// +build !gmp
package internal
import (
"crypto/rand"
"io"
"math/big"
"xdx.jelly/xgcl/internal/randutil"
)
type Int = big.Int
var bigOne = new(big.Int).SetInt64(1)
func FromBigInt(src *big.Int) *Int {
return src
}
func IntoBigInt(src *Int) *big.Int {
return src
}
func encrypt(c *big.Int, pub *PublicKey, m *big.Int) *big.Int {
e := big.NewInt(int64(pub.E))
c.Exp(m, e, pub.N)
return c
}
// decrypt performs an RSA decryption, resulting in a plaintext integer. If a
// random source is given, RSA blinding is used.
func decrypt(random io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err error) {
// TODO(agl): can we get away with reusing blinds?
if c.Cmp(priv.N) > 0 {
err = ErrDecryption
return
}
if priv.N.Sign() == 0 {
return nil, ErrDecryption
}
var ir *big.Int
if random != nil {
randutil.MaybeReadByte(random)
// Blinding enabled. Blinding involves multiplying c by r^e.
// Then the decryption operation performs (m^e * r^e)^d mod n
// which equals mr mod n. The factor of r can then be removed
// by multiplying by the multiplicative inverse of r.
var r *big.Int
ir = new(big.Int)
for {
r, err = rand.Int(random, priv.N)
if err != nil {
return
}
// if r.Cmp(bigZero) == 0 {
if r.Sign() == 0 {
r = bigOne
}
ok := ir.ModInverse(r, priv.N)
if ok != nil {
break
}
}
bigE := big.NewInt(int64(priv.E))
rpowe := new(big.Int).Exp(r, bigE, priv.N) // N != 0
cCopy := new(big.Int).Set(c)
cCopy.Mul(cCopy, rpowe)
cCopy.Mod(cCopy, priv.N)
c = cCopy
}
if priv.Precomputed.Dp == nil {
m = new(big.Int).Exp(c, priv.D, priv.N)
} else {
// We have the precalculated values needed for the CRT.
m = new(big.Int).Exp(c, priv.Precomputed.Dp, priv.Primes[0])
m2 := new(big.Int).Exp(c, priv.Precomputed.Dq, priv.Primes[1])
m.Sub(m, m2)
if m.Sign() < 0 {
m.Add(m, priv.Primes[0])
}
m.Mul(m, priv.Precomputed.Qinv)
m.Mod(m, priv.Primes[0])
m.Mul(m, priv.Primes[1])
m.Add(m, m2)
for i, values := range priv.Precomputed.CRTValues {
prime := priv.Primes[2+i]
m2.Exp(c, values.Exp, prime)
m2.Sub(m2, m)
m2.Mul(m2, values.Coeff)
m2.Mod(m2, prime)
if m2.Sign() < 0 {
m2.Add(m2, prime)
}
m2.Mul(m2, values.R)
m.Add(m, m2)
}
}
if ir != nil {
// Unblind.
m.Mul(m, ir)
m.Mod(m, priv.N)
}
return
}
+130
View File
@@ -0,0 +1,130 @@
//go:build gmp
// +build gmp
package internal
import (
"crypto/rand"
"io"
"math/big"
"xdx.jelly/xgcl/api/common"
"xdx.jelly/xgcl/internal/gmp"
"xdx.jelly/xgcl/internal/randutil"
)
type Int = gmp.Int
var bigOne = big.NewInt(1)
func FromBigInt(src *big.Int) *Int {
dst := new(Int)
dst.SetBytes(src.Bytes())
return dst
}
func IntoBigInt(src *Int) *big.Int {
dst := new(big.Int)
dst.SetBytes(src.Bytes())
return dst
}
func encrypt(c *big.Int, pub *PublicKey, m *big.Int) *big.Int {
e := new(Int).SetInt64(int64(pub.E))
cc := FromBigInt(c)
cc.Exp(FromBigInt(m), e, FromBigInt(pub.N))
c.SetBytes(cc.Bytes())
return c
}
// decrypt performs an RSA decryption, resulting in a plaintext integer. If a
// random source is given, RSA blinding is used.
func decrypt(random io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err error) {
// TODO(agl): can we get away with reusing blinds?
if c.Cmp(priv.N) > 0 {
err = common.SDR_KEYERR
return
}
if priv.N.Sign() == 0 {
return nil, common.SDR_KEYERR
}
var ir *Int
modulus := FromBigInt(priv.N)
d := FromBigInt(priv.D)
// if random != nil {
if false {
randutil.MaybeReadByte(random)
// Blinding enabled. Blinding involves multiplying c by r^e.
// Then the decryption operation performs (m^e * r^e)^d mod n
// which equals mr mod n. The factor of r can then be removed
// by multiplying by the multiplicative inverse of r.
var r *Int
ir = new(Int)
for {
var R *big.Int
R, err = rand.Int(random, priv.N)
if err != nil {
return
}
if R.Sign() == 0 {
R = bigOne
}
r = FromBigInt(R)
ok := ir.ModInverse(r, modulus)
if ok != nil {
break
}
}
bigE := new(Int).SetInt64(int64(priv.E))
rpowe := new(Int).Exp(r, bigE, modulus) // N != 0
cCopy := new(Int).Set(FromBigInt(c))
cCopy.Mul(cCopy, rpowe)
cCopy.Mod(cCopy, modulus)
c = IntoBigInt(cCopy)
}
var mm *Int
if priv.Precomputed.Dp == nil {
m = IntoBigInt(new(Int).Exp(FromBigInt(c), d, modulus))
} else {
// We have the precalculated values needed for the CRT.
cc := FromBigInt(c)
primes0 := FromBigInt(priv.Primes[0])
primes1 := FromBigInt(priv.Primes[1])
mm = new(Int).Exp(cc, FromBigInt(priv.Precomputed.Dp), primes0)
mm2 := new(Int).Exp(cc, FromBigInt(priv.Precomputed.Dq), primes1)
mm.Sub(mm, mm2)
if mm.Sign() < 0 {
mm.Add(mm, primes0)
}
mm.Mul(mm, FromBigInt(priv.Precomputed.Qinv))
mm.Mod(mm, primes0)
mm.Mul(mm, primes1)
mm.Add(mm, mm2)
for i, values := range priv.Precomputed.CRTValues {
prime := FromBigInt(priv.Primes[2+i])
mm2.Exp(cc, FromBigInt(values.Exp), prime)
mm2.Sub(mm2, mm)
mm2.Mul(mm2, FromBigInt(values.Coeff))
mm2.Mod(mm2, prime)
if mm2.Sign() < 0 {
mm2.Add(mm2, prime)
}
mm2.Mul(mm2, FromBigInt(values.R))
mm.Add(mm, mm2)
}
}
if ir != nil {
// Unblind.
mm.Mul(mm, ir)
mm.Mod(mm, modulus)
}
m = IntoBigInt(mm)
return
}
+693
View File
@@ -0,0 +1,693 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package rsa implements RSA encryption as specified in PKCS #1 and RFC 8017.
//
// RSA is a single, fundamental operation that is used in this package to
// implement either public-key encryption or public-key signatures.
//
// The original specification for encryption and signatures with RSA is PKCS #1
// and the terms "RSA encryption" and "RSA signatures" by default refer to
// PKCS #1 version 1.5. However, that specification has flaws and new designs
// should use version 2, usually called by just OAEP and PSS, where
// possible.
//
// Two sets of interfaces are included in this package. When a more abstract
// interface isn't necessary, there are functions for encrypting/decrypting
// with v1.5/OAEP and signing/verifying with v1.5/PSS. If one needs to abstract
// over the public key primitive, the PrivateKey type implements the
// Decrypter and Signer interfaces from the crypto package.
//
// The RSA operations in this package are not implemented using constant-time algorithms.
package internal
import (
"crypto"
cryptoRSA "crypto/rsa"
"crypto/subtle"
"errors"
"io"
"math/big"
"xdx.jelly/xgcl/api/common"
"xdx.jelly/xgcl/gmath"
"xdx.jelly/xgcl/internal/randutil"
"xdx.jelly/xgcl/sm"
)
// A PublicKey represents the public part of an RSA key.
type PublicKey struct {
N *big.Int // modulus
E int // public exponent
}
func NewPublicKey() *PublicKey {
return &PublicKey{
N: new(big.Int),
}
}
type PrecomputedValues = cryptoRSA.PrecomputedValues
// type PrecomputedValues struct {
// Dp, Dq *big.Int // D mod (P-1) (or mod Q-1)
// Qinv *big.Int // Q^-1 mod P
// // CRTValues is used for the 3rd and subsequent primes. Due to a
// // historical accident, the CRT for the first two primes is handled
// // differently in PKCS #1 and interoperability is sufficiently
// // important that we mirror this.
// CRTValues []CRTValue
// }
// CRTValue contains the precomputed Chinese remainder theorem values.
type CRTValue = cryptoRSA.CRTValue
// type CRTValue struct {
// Exp *big.Int // D mod (prime-1).
// Coeff *big.Int // R·Coeff ≡ 1 mod Prime.
// R *big.Int // product of primes prior to this (inc p and q).
// }
// A PrivateKey represents an RSA key
// type PrivateKey = rsa.PrivateKey
type PrivateKey struct {
PublicKey // public part.
D *big.Int // private exponent
Primes []*big.Int // prime factors of N, has >= 2 elements.
// Precomputed contains precomputed values that speed up private
// operations, if available.
Precomputed PrecomputedValues
}
func NewPrivateKey() *PrivateKey {
return &PrivateKey{
PublicKey: PublicKey{
N: new(big.Int),
},
D: new(big.Int),
Primes: []*big.Int{new(big.Int), new(big.Int)},
}
}
func (pub *PublicKey) From(k *cryptoRSA.PublicKey) {
pub.N = k.N
pub.E = k.E
}
func (pub *PublicKey) UnmarshalCryptoRsa(k *cryptoRSA.PublicKey) *PublicKey {
pub.From(k)
return pub
}
func (pub *PublicKey) Into() *cryptoRSA.PublicKey {
return &cryptoRSA.PublicKey{
N: pub.N,
E: pub.E,
}
}
func (pub *PublicKey) Equal(x crypto.PublicKey) bool {
switch xx := x.(type) {
case *PublicKey:
return pub.N.Cmp(xx.N) == 0 && pub.E == xx.E
case *cryptoRSA.PublicKey:
return pub.N.Cmp(xx.N) == 0 && pub.E == xx.E
default:
return false
}
}
func (priv *PrivateKey) From(k *cryptoRSA.PrivateKey) *PrivateKey {
priv.PublicKey.From(&k.PublicKey)
priv.D = k.D
priv.Primes = k.Primes
priv.Precomputed = k.Precomputed
return priv
}
func (priv *PrivateKey) Into() *cryptoRSA.PrivateKey {
return &cryptoRSA.PrivateKey{
PublicKey: cryptoRSA.PublicKey{
N: priv.PublicKey.N,
E: priv.PublicKey.E,
},
D: priv.D,
Primes: priv.Primes,
Precomputed: priv.Precomputed,
}
}
var (
errPublicModulus = errors.New("crypto/rsa: missing public modulus")
errPublicExponentSmall = errors.New("crypto/rsa: public exponent too small")
errPublicExponentLarge = errors.New("crypto/rsa: public exponent too large")
)
// checkPub sanity checks the public key before we use it.
// We require pub.E to fit into a 32-bit integer so that we
// do not have different behavior depending on whether
// int is 32 or 64 bits. See also
// https://www.imperialviolet.org/2012/03/16/rsae.html.
func checkPub(pub *PublicKey) error {
if pub.N == nil {
return errPublicModulus
}
if pub.E < 2 {
return errPublicExponentSmall
}
if pub.E > 1<<31-1 {
return errPublicExponentLarge
}
return nil
}
// Validate performs basic sanity checks on the key.
// It returns nil if the key is valid, or else an error describing a problem.
func (priv *PrivateKey) Validate() error {
if err := checkPub(&priv.PublicKey); err != nil {
return err
}
// Check that Πprimes == n.
modulus := new(big.Int).Set(bigOne)
for _, prime := range priv.Primes {
// Any primes ≤ 1 will cause divide-by-zero panics later.
if prime.Cmp(bigOne) <= 0 {
return errors.New("crypto/rsa: invalid prime value")
}
modulus.Mul(modulus, prime)
}
if modulus.Cmp(priv.N) != 0 {
return errors.New("crypto/rsa: invalid modulus")
}
// Check that de ≡ 1 mod p-1, for each prime.
// This implies that e is coprime to each p-1 as e has a multiplicative
// inverse. Therefore e is coprime to lcm(p-1,q-1,r-1,...) =
// exponent(/n). It also implies that a^de ≡ a mod p as a^(p-1) ≡ 1
// mod p. Thus a^de ≡ a mod n for all a coprime to n, as required.
congruence := new(big.Int)
de := new(big.Int).SetInt64(int64(priv.E))
de.Mul(de, priv.D)
for _, prime := range priv.Primes {
pminus1 := new(big.Int).Sub(prime, bigOne)
congruence.Mod(de, pminus1)
if congruence.Cmp(bigOne) != 0 {
return errors.New("crypto/rsa: invalid exponents")
}
}
return nil
}
// Precompute performs some calculations that speed up private key operations
// in the future.
func (priv *PrivateKey) Precompute() {
if priv.Precomputed.Dp != nil {
return
}
priv.Precomputed.Dp = new(big.Int).Sub(priv.Primes[0], bigOne)
priv.Precomputed.Dp.Mod(priv.D, priv.Precomputed.Dp)
priv.Precomputed.Dq = new(big.Int).Sub(priv.Primes[1], bigOne)
priv.Precomputed.Dq.Mod(priv.D, priv.Precomputed.Dq)
priv.Precomputed.Qinv = new(big.Int).ModInverse(priv.Primes[1], priv.Primes[0])
r := new(big.Int).Mul(priv.Primes[0], priv.Primes[1])
priv.Precomputed.CRTValues = make([]CRTValue, len(priv.Primes)-2)
for i := 2; i < len(priv.Primes); i++ {
prime := priv.Primes[i]
values := &priv.Precomputed.CRTValues[i-2]
values.Exp = new(big.Int).Sub(prime, bigOne)
values.Exp.Mod(priv.D, values.Exp)
values.R = new(big.Int).Set(r)
values.Coeff = new(big.Int).ModInverse(r, prime)
r.Mul(r, prime)
}
}
// UnmarshalSDF import privateKey from SDF type.
func (priv *PrivateKey) UnmarshalSDF(sdfPriv *common.RSArefPrivateKey) error {
return priv.FromSDF(sdfPriv)
}
func (priv *PrivateKey) FromSDF(sdfPriv *common.RSArefPrivateKey) error {
if priv.PublicKey.N == nil {
priv.PublicKey.N = new(big.Int)
}
priv.N.SetBytes(sdfPriv.M[:])
if priv.D == nil {
priv.D = new(big.Int)
}
priv.D.SetBytes(sdfPriv.D[:])
// E always be 65537
e := new(big.Int).SetBytes(sdfPriv.E[:])
if e.BitLen() > 32 {
return common.SDR_KEYERR
}
priv.E = int(e.Uint64())
priv.Primes = append(priv.Primes[:0], new(big.Int).SetBytes(sdfPriv.Prime[0][:]))
priv.Primes = append(priv.Primes, new(big.Int).SetBytes(sdfPriv.Prime[1][:]))
priv.Precompute()
return priv.Validate()
}
// Export export privateKey to SDF type.
func (priv *PrivateKey) IntoSDF() (*common.RSArefPrivateKey, error) {
ret := &common.RSArefPrivateKey{}
if err := priv.UnmarshalSDF(ret); err != nil {
return nil, err
}
return ret, nil
}
func (priv *PrivateKey) MarshalSDF(sdfPriv *common.RSArefPrivateKey) error {
if err := priv.Validate(); err != nil {
return err
}
priv.Precompute()
sdfPriv.Bits = uint32(priv.N.BitLen())
if sdfPriv.Bits > common.RSAref_MAX_BITS || len(priv.Primes) != 2 {
return common.SDR_KEYERR
}
_ = gmath.FillBytes(priv.N, sdfPriv.M[:])
_ = gmath.FillBytes(new(big.Int).SetInt64(int64(priv.E)), sdfPriv.E[:]) // FIXME
_ = gmath.FillBytes(priv.D, sdfPriv.D[:])
_ = gmath.FillBytes(priv.Primes[0], sdfPriv.Prime[0][:])
_ = gmath.FillBytes(priv.Primes[1], sdfPriv.Prime[1][:])
_ = gmath.FillBytes(priv.Precomputed.Dp, sdfPriv.Pexp[0][:])
_ = gmath.FillBytes(priv.Precomputed.Dq, sdfPriv.Pexp[1][:])
_ = gmath.FillBytes(priv.Precomputed.Qinv, sdfPriv.Coef[:])
return nil
}
// Set set pbulicKey directly by M and E, big-endian bytes.
func (pub *PublicKey) Set(M []byte, E []byte) error {
if pub.N == nil {
pub.N = new(big.Int)
}
pub.N.SetBytes(M[:])
e := new(Int).SetBytes(E[:])
if e.BitLen() > 32 {
return common.SDR_KEYERR
}
pub.E = int(e.Uint64())
return nil
}
func (pub *PublicKey) IntoSDF() (*common.RSArefPublicKey, error) {
ret := &common.RSArefPublicKey{}
if err := pub.MarshalSDF(ret); err != nil {
return nil, err
}
return ret, nil
}
// MarshalSDF export publicKey to SDF type.
func (pub *PublicKey) MarshalSDF(sdfPub *common.RSArefPublicKey) error {
if err := checkPub(pub); err != nil {
return err
}
sdfPub.Bits = uint32(pub.N.BitLen())
if sdfPub.Bits > common.RSAref_MAX_BITS {
return common.SDR_KEYERR
}
_ = gmath.FillBytes(pub.N, sdfPub.M[:])
_ = gmath.FillBytes(new(big.Int).SetInt64(int64(pub.E)), sdfPub.E[:]) // FIXME
return nil
}
// UnmarshalSDF import publicKey from SDF type.
func (pub *PublicKey) UnmarshalSDF(sdfPub *common.RSArefPublicKey) error {
return pub.FromSDF(sdfPub)
}
func (pub *PublicKey) FromSDF(sdfPub *common.RSArefPublicKey) error {
if pub.N == nil {
pub.N = new(big.Int)
}
pub.N.SetBytes(sdfPub.M[:])
e := new(big.Int).SetBytes(sdfPub.E[:])
if e.BitLen() > 32 {
return common.SDR_KEYERR
}
pub.E = int(e.Uint64())
return checkPub(pub)
}
// Size returns the modulus size in bytes. Raw signatures and ciphertexts
// for or by this public key will have the same size.
func (pub *PublicKey) Size() int {
return (pub.N.BitLen() + 7) / 8
}
// GenerateKey generates an RSA keypair of the given bit size using the
// random source random (for example, crypto/rand.Reader).
func GenerateKey(random io.Reader, bits int) (*PrivateKey, error) {
priv, err := cryptoRSA.GenerateKey(random, bits)
if err != nil {
return nil, err
}
privateKey := &PrivateKey{}
privateKey.From(priv)
return privateKey, nil
}
// ErrDecryption represents a failure to decrypt a message.
// It is deliberately vague to avoid adaptive attacks.
var ErrDecryption = errors.New("crypto/rsa: decryption error")
// ErrVerification represents a failure to verify a signature.
// It is deliberately vague to avoid adaptive attacks.
var ErrVerification = errors.New("crypto/rsa: verification error")
// ErrMessageTooLong is returned when attempting to encrypt a message which is
// too large for the size of the public key.
var ErrMessageTooLong = errors.New("crypto/rsa: message too long for RSA public key size")
// This file implements encryption and decryption using PKCS #1 v1.5 padding.
// PKCS1v15DecrypterOpts is for passing options to PKCS #1 v1.5 decryption using
// the crypto.Decrypter interface.
type PKCS1v15DecryptOptions = cryptoRSA.PKCS1v15DecryptOptions
// EncryptPKCS1v15 encrypts the given message with RSA and the padding
// scheme from PKCS #1 v1.5. The message must be no longer than the
// length of the public modulus minus 11 bytes.
//
// The rand parameter is used as a source of entropy to ensure that
// encrypting the same message twice doesn't result in the same
// ciphertext.
//
// WARNING: use of this function to encrypt plaintexts other than
// session keys is dangerous. Use RSA OAEP in new protocols.
func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) ([]byte, error) {
// return rsa.EncryptPKCS1v15(rand, pub.Into(), msg)
randutil.MaybeReadByte(rand)
if err := checkPub(pub); err != nil {
return nil, err
}
k := pub.Size()
if len(msg) > k-11 {
return nil, ErrMessageTooLong
}
// EM = 0x00 || 0x02 || PS || 0x00 || M
em := make([]byte, k)
em[1] = 2
ps, mm := em[2:len(em)-len(msg)-1], em[len(em)-len(msg):]
err := nonZeroRandomBytes(ps, rand)
if err != nil {
return nil, err
}
em[len(em)-len(msg)-1] = 0
copy(mm, msg)
m := new(big.Int).SetBytes(em)
c := encrypt(new(big.Int), pub, m)
gmath.FillBytes(c, em)
return em, nil
}
// DecryptPKCS1v15 decrypts a plaintext using RSA and the padding scheme from PKCS #1 v1.5.
// If rand != nil, it uses RSA blinding to avoid timing side-channel attacks.
//
// Note that whether this function returns an error or not discloses secret
// information. If an attacker can cause this function to run repeatedly and
// learn whether each instance returned an error then they can decrypt and
// forge signatures as if they had the private key. See
// DecryptPKCS1v15SessionKey for a way of solving this problem.
func DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) ([]byte, error) {
// return rsa.DecryptPKCS1v15(rand, priv.Into(), ciphertext)
if err := checkPub(&priv.PublicKey); err != nil {
return nil, err
}
valid, out, index, err := decryptPKCS1v15(rand, priv, ciphertext)
if err != nil {
return nil, err
}
if valid == 0 {
return nil, ErrDecryption
}
return out[index:], nil
}
// decryptPKCS1v15 decrypts ciphertext using priv and blinds the operation if
// rand is not nil. It returns one or zero in valid that indicates whether the
// plaintext was correctly structured. In either case, the plaintext is
// returned in em so that it may be read independently of whether it was valid
// in order to maintain constant memory access patterns. If the plaintext was
// valid then index contains the index of the original message in em.
func decryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (valid int, em []byte, index int, err error) {
k := priv.Size()
if k < 11 {
err = ErrDecryption
return
}
c := new(big.Int).SetBytes(ciphertext)
m, err := decrypt(rand, priv, c)
if err != nil {
return
}
em = m.FillBytes(make([]byte, k))
firstByteIsZero := subtle.ConstantTimeByteEq(em[0], 0)
secondByteIsTwo := subtle.ConstantTimeByteEq(em[1], 2)
// The remainder of the plaintext must be a string of non-zero random
// octets, followed by a 0, followed by the message.
// lookingForIndex: 1 iff we are still looking for the zero.
// index: the offset of the first zero byte.
lookingForIndex := 1
for i := 2; i < len(em); i++ {
equals0 := subtle.ConstantTimeByteEq(em[i], 0)
index = subtle.ConstantTimeSelect(lookingForIndex&equals0, i, index)
lookingForIndex = subtle.ConstantTimeSelect(equals0, 0, lookingForIndex)
}
// The PS padding must be at least 8 bytes long, and it starts two
// bytes into em.
validPS := subtle.ConstantTimeLessOrEq(2+8, index)
valid = firstByteIsZero & secondByteIsTwo & (^lookingForIndex & 1) & validPS
index = subtle.ConstantTimeSelect(valid, index+1, 0)
return valid, em, index, nil
}
// nonZeroRandomBytes fills the given slice with non-zero random octets.
func nonZeroRandomBytes(s []byte, rand io.Reader) (err error) {
_, err = io.ReadFull(rand, s)
if err != nil {
return
}
for i := 0; i < len(s); i++ {
for s[i] == 0 {
_, err = io.ReadFull(rand, s[i:i+1])
if err != nil {
return
}
// In tests, the PRNG may return all zeros so we do
// this to break the loop.
s[i] ^= 0x42
}
}
return
}
// These are ASN1 DER structures:
// DigestInfo ::= SEQUENCE {
// digestAlgorithm AlgorithmIdentifier,
// digest OCTET STRING
// }
// For performance, we don't use the generic ASN1 encoder. Rather, we
// precompute a prefix of the digest value that makes a valid ASN1 DER string
// with the correct contents.
var hashPrefixes = map[sm.Hash][]byte{
{Hash: crypto.SHA1}: {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14},
{Hash: crypto.SHA256}: {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20},
sm.SM3: {0x30, 0x2e, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x81, 0x1c, 0xcf, 0x55, 0x01, 0x83, 0x11, 0x01, 0x05, 0x00, 0x04, 0x20},
}
func pkcs1v15HashInfo(hash sm.Hash, inLen int) (hashLen int, prefix []byte, err error) {
// Special case: crypto.Hash(0) is used to indicate that the data is
// signed directly.
if hash.Hash == 0 {
return inLen, nil, nil
}
hashLen = hash.Size()
if inLen != hashLen {
return 0, nil, errors.New("gcl/rsa: input must be hashed message")
}
prefix, ok := hashPrefixes[hash]
if !ok {
return 0, nil, errors.New("gcl/rsa: unsupported hash function")
}
return
}
// SignPKCS1v15 calculates the signature of hashed using
// RSASSA-PKCS1-V1_5-SIGN from RSA PKCS #1 v1.5. Note that hashed must
// be the result of hashing the input message using the given hash
// function. If hash is zero, hashed is signed directly. This isn't
// advisable except for interoperability.
//
// If rand is not nil then RSA blinding will be used to avoid timing
// side-channel attacks.
//
// This function is deterministic. Thus, if the set of possible
// messages is small, an attacker may be able to build a map from
// messages to signatures and identify the signed messages. As ever,
// signatures provide authenticity, not confidentiality.
func SignPKCS1v15(rand io.Reader, priv *PrivateKey, hash sm.Hash, hashed []byte) ([]byte, error) {
hashLen, prefix, err := pkcs1v15HashInfo(hash, len(hashed))
if err != nil {
return nil, err
}
tLen := len(prefix) + hashLen
k := priv.Size()
if k < tLen+11 {
return nil, errors.New("rsa: message too long for RSA public key size")
}
// EM = 0x00 || 0x01 || PS || 0x00 || T
em := make([]byte, k)
em[1] = 1
for i := 2; i < k-tLen-1; i++ {
em[i] = 0xff
}
copy(em[k-tLen:k-hashLen], prefix)
copy(em[k-hashLen:k], hashed)
m := new(big.Int).SetBytes(em)
c, err := decryptAndCheck(rand, priv, m)
if err != nil {
return nil, err
}
return c.FillBytes(em), nil
// return rsa.SignPKCS1v15(rand, priv, hash.Hash, hashed)
}
// VerifyPKCS1v15 verifies an RSA PKCS #1 v1.5 signature.
// hashed is the result of hashing the input message using the given hash
// function and sig is the signature. A valid signature is indicated by
// returning a nil error. If hash is zero then hashed is used directly. This
// isn't advisable except for interoperability.
func VerifyPKCS1v15(pub *PublicKey, hash sm.Hash, hashed []byte, sig []byte) error {
hashLen, prefix, err := pkcs1v15HashInfo(hash, len(hashed))
if err != nil {
return err
}
tLen := len(prefix) + hashLen
k := pub.Size()
if k < tLen+11 {
return ErrVerification
}
// RFC 8017 Section 8.2.2: If the length of the signature S is not k
// octets (where k is the length in octets of the RSA modulus n), output
// "invalid signature" and stop.
if k != len(sig) {
return ErrVerification
}
c := new(big.Int).SetBytes(sig)
m := encrypt(new(big.Int), pub, c)
em := m.FillBytes(make([]byte, k))
// EM = 0x00 || 0x01 || PS || 0x00 || T
ok := subtle.ConstantTimeByteEq(em[0], 0)
ok &= subtle.ConstantTimeByteEq(em[1], 1)
ok &= subtle.ConstantTimeCompare(em[k-hashLen:k], hashed)
ok &= subtle.ConstantTimeCompare(em[k-tLen:k-hashLen], prefix)
ok &= subtle.ConstantTimeByteEq(em[k-tLen-1], 0)
for i := 2; i < k-tLen-1; i++ {
ok &= subtle.ConstantTimeByteEq(em[i], 0xff)
}
if ok != 1 {
return ErrVerification
}
return nil
// return rsa.VerifyPKCS1v15(pub, hash.Hash, hashed, sig)
}
func decryptAndCheck(random io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err error) {
m, err = decrypt(random, priv, c)
if err != nil {
return nil, err
}
// In order to defend against errors in the CRT computation, m^e is
// calculated, which should match the original ciphertext.
check := encrypt(new(big.Int), &priv.PublicKey, m)
if c.Cmp(check) != 0 {
return nil, errors.New("rsa: internal error")
}
return m, nil
}
// PublicKeyOperationRSA RSA公钥运算。数据格式由应用层封装。inData 应该小于 privateKey.Size()
func PublicKeyOperationRSA(publicKey *PublicKey, inData []byte) ([]byte, error) {
m := new(big.Int).SetBytes(inData)
if m.Cmp(publicKey.N) >= 0 {
return nil, common.SDR_INARGERR
}
c := encrypt(new(big.Int), publicKey, m)
ret := make([]byte, common.RSAref_MAX_LEN)
err := gmath.FillBytes(c, ret)
return ret, err
}
// PrivateKeyOperationRSA RSA私钥运算。数据格式由应用层封装。inData 应该小于 privateKey.Bits/8
func PrivateKeyOperationRSA(privateKey *PrivateKey, inData []byte) ([]byte, error) {
c := new(big.Int).SetBytes(inData)
if c.Cmp(privateKey.N) >= 0 {
return nil, common.SDR_INARGERR
}
m, err := decrypt(nil, privateKey, c)
if err != nil {
return nil, err
}
ret := make([]byte, common.RSAref_MAX_LEN)
err = gmath.FillBytes(m, ret)
return ret, err
}
// Sign implements the crypto.Signer interface
func (priv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) {
if pssOpts, ok := opts.(*cryptoRSA.PSSOptions); ok {
return cryptoRSA.SignPSS(rand, priv.Into(), pssOpts.Hash, digest, pssOpts)
}
return SignPKCS1v15(rand, priv, sm.Hash{Hash: opts.HashFunc()}, digest)
}
func (priv *PrivateKey) Public() crypto.PublicKey {
return &priv.PublicKey
}
+21
View File
@@ -0,0 +1,21 @@
package rsa
import (
"xdx.jelly/xgcl/rsa/internal"
"xdx.jelly/xgcl/sm"
)
var PKCS1v15WithSha256Options = sm.SHA256
var PKCS1v15WithSha1Options = sm.SHA1
var PKCS1v15WithSm3Options = sm.SM3
// PrivateKey export internal.PrivateKey.
type PrivateKey = internal.PrivateKey
// PublicKey export internal.PublicKey
type PublicKey = internal.PublicKey
var NewPrivateKey = internal.NewPrivateKey
var NewPublicKey = internal.NewPublicKey
var GenerateKey = internal.GenerateKey
+247
View File
@@ -0,0 +1,247 @@
package rsa
import (
"bytes"
"crypto"
cryptoRSA "crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"
"testing"
"time"
"xdx.jelly/xgcl/api/common"
)
func BenchmarkKey(t *testing.B) {
_, _, _ = PKCS1v15{}.GenerateKeyPairRSA(2048)
}
func TestKeyGen(t *testing.T) {
sk, pk, _ := PKCS1v15{}.GenerateKeyPairRSA(1024)
fmt.Println(sk.D.Text(16))
fmt.Println(pk.E)
fmt.Println(pk.N.Text(16))
}
func TestKey(t *testing.T) {
sk, pk, _ := PKCS1v15{}.GenerateKeyPairRSA(2048)
sk1 := sk
pk1 := pk
var sdfPriv common.RSArefPrivateKey
var sdfPub common.RSArefPublicKey
if err := sk.MarshalSDF(&sdfPriv); err != nil {
t.Log("sk.MarshalSDF failed")
t.Fail()
}
if err := sk.UnmarshalSDF(&sdfPriv); err != nil || sk != sk1 {
t.Log("sk.UnmarshalSDF failed")
t.Fail()
}
if err := pk.MarshalSDF(&sdfPub); err != nil {
t.Log("pk.MarshalSDF failed")
t.Fail()
}
if err := pk.UnmarshalSDF(&sdfPub); err != nil || pk != pk1 {
t.Log("pk.UnmarshalSDF failed")
t.Fail()
}
}
//RAW签摘要
func TestRSARAWSign(t *testing.T) {
// sha256摘要
msg := []byte("message")
digestData := sha256.Sum256(msg)
sk, pk, err := PKCS1v15{}.GenerateKeyPairRSA(2048)
fmt.Printf("N:%s\n", sk.N.Text(16)) // sig is the same each time
// 签名值。2048bit integer
signData, err := PKCS1v15{}.Sign(sk, crypto.SHA256, digestData[:])
fmt.Printf("sig:%02x\n", signData) // sig is the same each time
err = PKCS1v15{}.Verify(pk, crypto.SHA256, digestData[:], signData)
if err != nil {
t.Log("verify failed")
t.Fail()
}
}
func rsaRAWVerifyDigest(certPEM string, signData []byte, digestData []byte) error {
block, _ := pem.Decode([]byte(certPEM))
if block == nil {
return fmt.Errorf("failed to decode certificate PEM")
}
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return fmt.Errorf("failed to parse certificate PEM")
}
if cert.PublicKeyAlgorithm != x509.RSA {
return fmt.Errorf("not rsa algorithm")
}
pk, ok := cert.PublicKey.(*cryptoRSA.PublicKey)
if !ok {
return fmt.Errorf("failed to get publickey")
}
var hash crypto.Hash
switch cert.SignatureAlgorithm {
case x509.SHA1WithRSA:
hash = crypto.SHA1
case x509.SHA256WithRSA:
hash = crypto.SHA256
case x509.SHA384WithRSA:
hash = crypto.SHA384
case x509.SHA512WithRSA:
hash = crypto.SHA512
}
return PKCS1v15{}.Verify((&PublicKey{}).UnmarshalCryptoRsa(pk), hash, digestData, signData)
}
//RAW验摘要
func TestRSARAWVerifyDigest(t *testing.T) {
digestData, _ := base64.StdEncoding.DecodeString("ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0=")
signData, _ := base64.StdEncoding.DecodeString("OkXl4owB9VncVmnUXSgQxwMwy8KVuFXk1e9vtOdrXEAOiAXbc6WYjmbT4tdoiEIj02ZaAT449QxQ2fkAsD4IP6iyrmP4Q34qlD5mbh3unuAchLW+XYuDFzVLMp2BLBw2aN/OmjaQdZo6GKy6h5RvrXgf+FwRwI1RIi4r+heA3mlnkUejSJXMkXsbamxMfTO+DH9GBv5cbSwLOEyGcnq/M7urIo/esZT5f+RXwIiI1Z+Qs+1UQ8WJ5O9oBgkJp4BY+o9oaEPuEIMsR0Hz94zv+9+CGn1G0xoBYVOxlRLWYsCyRYnwXzL/2jkJ3GAY3HQyiGa8WRB2LT+C2ijNK3D/nA==")
certPEM := "MIIDiTCCAnGgAwIBAgIKb0XKECkuAA7e5jANBgkqhkiG9w0BAQsFADAlMRUwEwYDVQQDDAxBQkMgVEVTVCBDQTIxDDAKBgNVBAoMA0FCQzAeFw0xODA0MDIwMDQ4MzFaFw0yMzA0MDIwMDQ4MzFaME4xLzAtBgNVBAMMJjQ0OTk0NDIxMzAwLjAwMDUuMDAwMC42NjQ0NTAyNTY2MjY5NTAxMQ0wCwYDVQQLDARVd2luMQwwCgYDVQQKDANBQkMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCHbgJr3CmQf69XOK27F4V3YDCfvnH2JcL4xDxHd2B2Sy29NeU4bFsCZaBTc2N3ujHTLSRn+NEuFE90aejd/TvvuDzKda0r0615wo5NUfQiY5pi7UQ3k1IXtSpuImlIdPhnS0egBHropMQgd1f1K+54bSWB9+vhCIATP9GDQS32fJ2z3If0E3T5fCKiS4KS+SBhwtvEEMisCbDpD2y+BwYz0Ozkth9SrJ6r+ujLGwu5JYD/YRL7or8lpi575KvT6Ahf0iDZ/bzLjyZ5rWjSAWWAPJCjUoOFDt9XhY5fTo4B0lj6RV96qyCIau8n+fSVIiqXfxK5/W+iHj9zTXfe2sNbAgMBAAGjgZEwgY4wHwYDVR0jBBgwFoAUErtyLm5Iqy6z01KtzsJ33EmoKtIwCQYDVR0TBAIwADBBBgNVHR8EOjA4MDagNKAypDAwLjEQMA4GA1UEAwwHY3JsNDQ5MjEMMAoGA1UECwwDY3JsMQwwCgYDVQQKDANBQkMwHQYDVR0OBBYEFAHfn4lC2TqykHQ9dIhle8y1d7TyMA0GCSqGSIb3DQEBCwUAA4IBAQAwjLw04jTEDh06UepD7pjmH7rcmqOeXMsfPRLPF1vG2w8dOAvwH7fUIRYWKx4i9uM/mue5rYZokP5p8bV/Gx1+KNEEK7LOgUKlHjc5U/HVa89SnynWCUs9tD1DDM25BSb9szzwUz0QG5XNgskn7h3LsXoUdzXV+j+eIYuIY3q/TURN/3ds7if+0zwnaFwj9PpUcB3A9ShynhpZX6xBLMH3WT8MofUdzVmvZDPxaGxBpORQL8ZlXdU34aeHX9290lBTqH3TxXXEuWoBfzW2cp0j5daoGh9VX7Qh93d3mj+vZKv/W6B0GmNfEiABCNUrN1x4nz7jK1yyMu1j9rJTSXOQ"
certPEM = "-----BEGIN CERTIFICATE-----\n" + certPEM + "\n-----END CERTIFICATE-----"
err := rsaRAWVerifyDigest(certPEM, signData, digestData)
if err != nil {
t.Log("verify failed")
t.Fail()
}
}
func TestSpeed(t *testing.T) {
msg := []byte("message")
digestData := sha256.Sum256(msg)
sk, pk, _ := PKCS1v15{}.GenerateKeyPairRSA(2048)
// sk.Precompute()
var signData []byte
for i := 0; i < 1000; i++ {
signData, _ = PKCS1v15{}.Sign(sk, crypto.SHA256, digestData[:])
}
cnt := 1000
start := time.Now()
for i := 0; i < cnt; i++ {
signData, _ = PKCS1v15{}.Sign(sk, crypto.SHA256, digestData[:])
}
end := time.Now()
elapsed := end.Sub(start)
fmt.Printf("Sign %d, used time: %d ms, %d pcs/s\n", cnt, elapsed.Milliseconds(), int(float64(cnt)/float64(elapsed.Milliseconds())*1000))
start = time.Now()
for i := 0; i < cnt; i++ {
_ = PKCS1v15{}.Verify(pk, crypto.SHA256, digestData[:], signData)
}
end = time.Now()
elapsed = end.Sub(start)
fmt.Printf("verify %d, used time: %d ms, %d pcs/s\n", cnt, elapsed.Milliseconds(), int(float64(cnt)/float64(elapsed.Milliseconds())*1000))
}
func BenchmarkSign(b *testing.B) {
msg := []byte("message")
digestData := sha256.Sum256(msg)
sk, _, _ := PKCS1v15{}.GenerateKeyPairRSA(1024 * 2)
b.StartTimer()
_, _ = PKCS1v15{}.Sign(sk, crypto.SHA256, digestData[:])
b.StopTimer()
}
func BenchmarkVerify(b *testing.B) {
msg := []byte("message")
digestData := sha256.Sum256(msg)
sk, pk, _ := PKCS1v15{}.GenerateKeyPairRSA(2048)
signData, _ := PKCS1v15{}.Sign(sk, crypto.SHA256, digestData[:])
b.StartTimer()
_ = PKCS1v15{}.Verify(pk, crypto.SHA256, digestData[:], signData)
b.StopTimer()
}
func TestRsaSdf(t *testing.T) {
impl := PKCS1v15{}
sk, pk, err := impl.GenerateKeyPairRSA(2048)
if err != nil || sk.Validate() != nil {
t.Log("GenerateKeyPairRSA failed")
t.Fail()
return
}
envelopedKeyPair, err := impl.GenerateEnvelopedKeyPairRSA(1024, pk)
if err != nil {
t.Log("GenerateEnvelopedKeyPairRSA failed")
t.Fail()
return
}
sk1, pk1, err := impl.ImportEnvelopedKeyPairRSA(envelopedKeyPair, sk)
if err != nil || sk1.Validate() != nil {
t.Log("ImportEnvelopedKeyPairRSA failed", err)
t.Fail()
return
}
sessionKey, encryptedSessionKey, err := impl.GenerateKeyRSA(16, pk)
if err != nil {
t.Log("GenerateKeyRSA failed")
t.Fail()
return
}
encryptedSessionKey, err = impl.ExchangeDigitEnvelopeRSA(sk, pk1, encryptedSessionKey)
if err != nil {
t.Log("ExchangeDigitEnvelopeRSA failed")
t.Fail()
return
}
decrytpedSessionKey, err := impl.ImportKeyRSA(16, sk1, encryptedSessionKey)
if err != nil {
t.Log("ImportKeyRSA failed")
t.Fail()
return
}
if bytes.Compare(sessionKey, decrytpedSessionKey) != 0 {
t.Log("sessionkey not equal")
t.Fail()
return
}
data := make([]byte, pk.Size())
data[0] = 1
encryptedData, err := impl.PublicKeyOperationRSA(pk, data)
if err != nil {
t.Log("PublicKeyOperationRSA failed")
t.Fail()
return
}
decryptedData, err := impl.PrivateKeyOperationRSA(sk, encryptedData)
if err != nil {
t.Log("PrivateKeyOperationRSA failed")
t.Fail()
return
}
if bytes.Compare(data, decryptedData) != 0 {
t.Log("PublicKeyOperationRSA/PrivateKeyOperationRSA failed")
t.Fail()
return
}
}
+179
View File
@@ -0,0 +1,179 @@
package rsa
import (
"math/big"
"xdx.jelly/xgcl/api/common"
"xdx.jelly/xgcl/gmath"
"xdx.jelly/xgcl/grand"
"xdx.jelly/xgcl/identifier"
"xdx.jelly/xgcl/rsa/internal"
"xdx.jelly/xgcl/sm/sm4"
)
// GenerateKeyPairRSA corresponding to SDF_GenerateKeyPair_RSA
func (PKCS1v15) GenerateKeyPairRSA(keyBits uint32) (*PrivateKey, *PublicKey, error) {
if keyBits > common.RSAref_MAX_BITS {
return nil, nil, common.SDR_KEYERR
}
privateKey, err := internal.GenerateKey(grand.Reader, int(keyBits))
// privateKey, err := internal.GenerateKey(rand.New(rand.NewSource(1234)), int(keyBits))
if err != nil {
return nil, nil, common.SDR_KEYERR
}
return privateKey, &privateKey.PublicKey, nil
}
// GenerateEnvelopedKeyPairRSA 生成密钥对保护结构并用publicKey加密输出。
// 对应SDF_GenerateRSAKeyPairWithIPK_RSA和SDF_GenerateRSAKeyPairWithEPK_RSA
// 注意:内部不检查keyBits.
func (p PKCS1v15) GenerateEnvelopedKeyPairRSA(keyBits uint32, publicKey *PublicKey) (*common.EnvelopedRSAKey, error) {
sm4key := make([]byte, sm4.BlockSize)
n, err := grand.GenerateRandom(sm4key)
if n < sm4.BlockSize || err != nil {
return nil, common.SDR_RANDERR
}
sk, pk, err := p.GenerateKeyPairRSA(keyBits)
if err != nil {
return nil, err
}
enveloped := common.EnvelopedRSAKey{
SymmAlgID: identifier.SGDSM4ECB,
Bits: keyBits,
}
var data [common.RSAref_MAX_LEN]byte
buf := data[:]
buf0 := data[:common.RSAref_MAX_PLEN]
gmath.FillBytes(sk.N, buf)
copy(enveloped.EncryptedPriKey[0][:], buf[:common.RSAref_MAX_PLEN])
copy(enveloped.EncryptedPriKey[1][:], buf[common.RSAref_MAX_PLEN:])
gmath.FillBytes(new(big.Int).SetInt64(int64(sk.E)), buf)
copy(enveloped.EncryptedPriKey[2][:], buf[:common.RSAref_MAX_PLEN])
copy(enveloped.EncryptedPriKey[3][:], buf[common.RSAref_MAX_PLEN:])
gmath.FillBytes(sk.D, buf)
copy(enveloped.EncryptedPriKey[4][:], buf[:common.RSAref_MAX_PLEN])
copy(enveloped.EncryptedPriKey[5][:], buf[common.RSAref_MAX_PLEN:])
if len(sk.Primes) != 2 {
return nil, common.SDR_KEYERR
}
gmath.FillBytes(sk.Primes[0], buf0)
copy(enveloped.EncryptedPriKey[6][:], buf0)
gmath.FillBytes(sk.Primes[1], buf0)
copy(enveloped.EncryptedPriKey[7][:], buf0)
gmath.FillBytes(sk.Precomputed.Dp, buf0)
copy(enveloped.EncryptedPriKey[8][:], buf0)
gmath.FillBytes(sk.Precomputed.Dq, buf0)
copy(enveloped.EncryptedPriKey[9][:], buf0)
gmath.FillBytes(sk.Precomputed.Qinv, buf0)
copy(enveloped.EncryptedPriKey[10][:], buf0)
for i := 0; i < len(enveloped.EncryptedPriKey); i++ {
sm4.EncryptECB(enveloped.EncryptedPriKey[i][:], sm4key, enveloped.EncryptedPriKey[i][:])
}
err = pk.MarshalSDF(&enveloped.PubKey)
if err != nil {
return nil, common.SDR_UNKNOWERR
}
C, err := internal.EncryptPKCS1v15(grand.Reader, publicKey, sm4key)
if err != nil {
return nil, common.SDR_KEYERR
}
enveloped.L = uint32(len(C))
copy(enveloped.C[:], C)
return &enveloped, nil
}
// ImportEnvelopedKeyPairRSA 导入RSA密钥保护结构。
func (PKCS1v15) ImportEnvelopedKeyPairRSA(envelopedRSAKey *common.EnvelopedRSAKey, privateKey *PrivateKey) (*PrivateKey, *PublicKey, error) {
sk := internal.NewPrivateKey()
sm4key, err := internal.DecryptPKCS1v15(grand.Reader, privateKey, envelopedRSAKey.C[:envelopedRSAKey.L])
if err != nil || len(sm4key) != sm4.BlockSize {
return nil, nil, common.SDR_INARGERR
}
for i := 0; i < len(envelopedRSAKey.EncryptedPriKey); i++ {
sm4.DecryptECB(envelopedRSAKey.EncryptedPriKey[i][:], sm4key, envelopedRSAKey.EncryptedPriKey[i][:])
}
var data [common.RSAref_MAX_LEN]byte
buf := data[:]
copy(buf[:common.RSAref_MAX_PLEN], envelopedRSAKey.EncryptedPriKey[0][:])
copy(buf[common.RSAref_MAX_PLEN:], envelopedRSAKey.EncryptedPriKey[1][:])
sk.N.SetBytes(buf)
copy(buf[:common.RSAref_MAX_PLEN], envelopedRSAKey.EncryptedPriKey[2][:])
copy(buf[common.RSAref_MAX_PLEN:], envelopedRSAKey.EncryptedPriKey[3][:])
sk.E = int(new(big.Int).SetBytes(buf).Int64())
copy(buf[:common.RSAref_MAX_PLEN], envelopedRSAKey.EncryptedPriKey[4][:])
copy(buf[common.RSAref_MAX_PLEN:], envelopedRSAKey.EncryptedPriKey[5][:])
sk.D.SetBytes(buf)
sk.Primes[0].SetBytes(envelopedRSAKey.EncryptedPriKey[6][:])
sk.Primes[1].SetBytes(envelopedRSAKey.EncryptedPriKey[7][:])
sk.Precompute()
return sk, &sk.PublicKey, nil
}
// GenerateKeyRSA 生成会话密钥并用publicKey加密输出
func (PKCS1v15) GenerateKeyRSA(keyBits uint32, publicKey *PublicKey) ([]byte, []byte, error) {
key := make([]byte, keyBits)
c, err := internal.EncryptPKCS1v15(grand.Reader, publicKey, key)
if err != nil {
return nil, nil, common.SDR_KEYERR
}
return key, c, nil
}
// GenerateKeyRSA 导入会话密钥密文encryptedKey,并用privateKey解密。返回会话密钥。
func (PKCS1v15) ImportKeyRSA(keyBits uint32, privateKey *PrivateKey, encryptedKey []byte) ([]byte, error) {
key, err := internal.DecryptPKCS1v15(grand.Reader, privateKey, encryptedKey)
if err != nil || len(key) != int(keyBits) {
return nil, common.SDR_INARGERR
}
return key, nil
}
// ExchangeDigitEnvelopeRSA 基于RSA的数字信封转换,privateKey解密会话密钥密文,再用publicKey加密会话密文。
// inKey: 输入会话密钥密文
// 返回: 转换后的会话密文
func (PKCS1v15) ExchangeDigitEnvelopeRSA(privateKey *PrivateKey, publicKey *PublicKey, inKey []byte) ([]byte, error) {
key, err := internal.DecryptPKCS1v15(grand.Reader, privateKey, inKey)
if err != nil {
return nil, common.SDR_INARGERR
}
c, err := internal.EncryptPKCS1v15(grand.Reader, publicKey, key)
if err != nil {
return nil, common.SDR_KEYERR
}
return c, nil
}
// PublicKeyOperationRSA RSA公钥运算。数据格式由应用层封装。inData 应该小于 privateKey.Size()
func (PKCS1v15) PublicKeyOperationRSA(publicKey *PublicKey, inData []byte) ([]byte, error) {
return internal.PublicKeyOperationRSA(publicKey, inData)
}
// PrivateKeyOperationRSA RSA私钥运算。数据格式由应用层封装。inData 应该小于 privateKey.Bits/8
func (PKCS1v15) PrivateKeyOperationRSA(privateKey *PrivateKey, inData []byte) ([]byte, error) {
return internal.PrivateKeyOperationRSA(privateKey, inData)
}
+49
View File
@@ -0,0 +1,49 @@
package rsa
import (
"crypto"
"xdx.jelly/xgcl/rsa/internal"
"xdx.jelly/xgcl/sm"
)
var VerifyPKCS1v15 = internal.VerifyPKCS1v15
var SignPKCS1v15 = internal.SignPKCS1v15
// helper function for RSA_SM3 signature
// SignPKCS1v15WithSm3 signature with SM3
func SignPKCS1v15WithSm3(priv *PrivateKey, hashed []byte) ([]byte, error) {
return SignPKCS1v15(nil, priv, sm.SM3, hashed)
}
// SignPKCS1v15WithSm3 signature with SHA256
func SignPKCS1v15WithSha256(priv *PrivateKey, hashed []byte) ([]byte, error) {
return SignPKCS1v15(nil, priv, sm.SHA256, hashed)
}
// VerifyPKCS1v15WithSm3 verify with SM3
func VerifyPKCS1v15WithSm3(pub *PublicKey, hashed []byte, sig []byte) error {
return VerifyPKCS1v15(pub, sm.SM3, hashed, sig)
}
// VerifyPKCS1v15WithSha256 verify with SHA256
func VerifyPKCS1v15WithSha256(pub *PublicKey, hashed []byte, sig []byte) error {
return VerifyPKCS1v15(pub, sm.SHA256, hashed, sig)
}
// PKCS1v15 implement the sdf.RSAAdapter interface
type PKCS1v15 struct{}
// 0018用的是PKCS1v1.5 还有其他暂不实现
func NewPKCS1v15() PKCS1v15 {
return PKCS1v15{}
}
func (PKCS1v15) Sign(priv *PrivateKey, hash crypto.Hash, hashed []byte) ([]byte, error) {
return internal.SignPKCS1v15(nil, priv, sm.Hash{Hash: hash}, hashed)
}
func (PKCS1v15) Verify(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) error {
return internal.VerifyPKCS1v15(pub, sm.Hash{Hash: hash}, hashed, sig)
}