WIP RSA support
This commit is contained in:
30
crypto/rsa/key.go
Normal file
30
crypto/rsa/key.go
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package rsa
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
MultibaseCode = uint64(0x1205)
|
||||||
|
|
||||||
|
MinRsaKeyBits = 2048
|
||||||
|
MaxRsaKeyBits = 8192
|
||||||
|
)
|
||||||
|
|
||||||
|
func GenerateKeyPair(bits int) (*PublicKey, *PrivateKey, error) {
|
||||||
|
if bits < MinRsaKeyBits || bits > MaxRsaKeyBits {
|
||||||
|
return nil, nil, fmt.Errorf("invalid key size: %d", bits)
|
||||||
|
}
|
||||||
|
priv, err := rsa.GenerateKey(rand.Reader, bits)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
return &PublicKey{k: &priv.PublicKey}, &PrivateKey{k: priv}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
pemPubBlockType = "PUBLIC KEY"
|
||||||
|
pemPrivBlockType = "PRIVATE KEY"
|
||||||
|
)
|
||||||
89
crypto/rsa/key_test.go
Normal file
89
crypto/rsa/key_test.go
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
package rsa
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/INFURA/go-did/crypto/_testsuite"
|
||||||
|
)
|
||||||
|
|
||||||
|
var harness = testsuite.TestHarness[*PublicKey, *PrivateKey]{
|
||||||
|
Name: "rsa-2048",
|
||||||
|
GenerateKeyPair: func() (*PublicKey, *PrivateKey, error) { return GenerateKeyPair(2048) },
|
||||||
|
PublicKeyFromPublicKeyMultibase: PublicKeyFromPublicKeyMultibase,
|
||||||
|
PublicKeyFromX509DER: PublicKeyFromX509DER,
|
||||||
|
PublicKeyFromX509PEM: PublicKeyFromX509PEM,
|
||||||
|
PrivateKeyFromPKCS8DER: PrivateKeyFromPKCS8DER,
|
||||||
|
PrivateKeyFromPKCS8PEM: PrivateKeyFromPKCS8PEM,
|
||||||
|
MultibaseCode: MultibaseCode,
|
||||||
|
SignatureBytesSize: 123456,
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSuite(t *testing.T) {
|
||||||
|
testsuite.TestSuite(t, harness)
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkSuite(b *testing.B) {
|
||||||
|
testsuite.BenchSuite(b, harness)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPublicKeyX509(t *testing.T) {
|
||||||
|
// openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048
|
||||||
|
// openssl pkey -in private_key.pem -pubout -out public_key.pem
|
||||||
|
pem := `-----BEGIN PUBLIC KEY-----
|
||||||
|
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyLFQUbVVo/rctJaCzR5z
|
||||||
|
g622eUNBwZmA1vnDEXnHWBl3y5RJF5zyTdlouujjmEuu6qsXk1NCNQ3dLH2iquI8
|
||||||
|
iFFAhS4kTX6JS+wR3vHLhga1oFkPceGFEUG/3vxn52ozFs8hikhq/P09HmLub7Vc
|
||||||
|
VklwrGvTbEa5Fn/2Kz6olw5ExYI14Unsl+A3iw8AXPL9/acD+ehoyx3/zKFrVTKx
|
||||||
|
e9jdoWX8L7IpqM2HOSu23/3E2IwH2GdY0C8575AiD/O555hie7JHkzF3I4E85gPd
|
||||||
|
ZgXYFShIfgOzDV0q4oP0pzqYkErhdjOpigCMjDuIC4OueZYqYJrP2rdpzuqoqk07
|
||||||
|
NwIDAQAB
|
||||||
|
-----END PUBLIC KEY-----
|
||||||
|
`
|
||||||
|
|
||||||
|
pub, err := PublicKeyFromX509PEM(pem)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
rt := pub.ToX509PEM()
|
||||||
|
require.Equal(t, pem, rt)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrivateKeyPKCS8(t *testing.T) {
|
||||||
|
// openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048
|
||||||
|
pem := `-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDIsVBRtVWj+ty0
|
||||||
|
loLNHnODrbZ5Q0HBmYDW+cMRecdYGXfLlEkXnPJN2Wi66OOYS67qqxeTU0I1Dd0s
|
||||||
|
faKq4jyIUUCFLiRNfolL7BHe8cuGBrWgWQ9x4YURQb/e/GfnajMWzyGKSGr8/T0e
|
||||||
|
Yu5vtVxWSXCsa9NsRrkWf/YrPqiXDkTFgjXhSeyX4DeLDwBc8v39pwP56GjLHf/M
|
||||||
|
oWtVMrF72N2hZfwvsimozYc5K7bf/cTYjAfYZ1jQLznvkCIP87nnmGJ7skeTMXcj
|
||||||
|
gTzmA91mBdgVKEh+A7MNXSrig/SnOpiQSuF2M6mKAIyMO4gLg655lipgms/at2nO
|
||||||
|
6qiqTTs3AgMBAAECggEAVFVqZoN4QumSYBKVUYOX0AAp2ygflC6gnPWkeo39bjB5
|
||||||
|
jiM4WcNacMtIvq5JoYBANx2BUSfd/PRf+ierOPrLrA7UuYJLwALJyA0h71kVCLN+
|
||||||
|
FC0Il/bIF5nU+mt/cBfI8y9ELVtEFh6GVeQFxQxlil7fCZ1f4TKQ6XsJI1/3sU2P
|
||||||
|
hbOuyfKKiWym8n5BV6NP3gotjnT01I+seplx3oMOKIaGl0KMgkuU2r8o8WMjA7Gx
|
||||||
|
1WWPJDpUdyYDYSUH8PubXowHkE+2RXddZ+tGvS8mF/A4Q0hdj2T9XvzyZ813O9Tv
|
||||||
|
n522A9QQE8YlqwAYh4z3VoNhz+Fi1mQfYsIblNygSQKBgQDrk+kB/dz92RPhP/rh
|
||||||
|
zAOvwRuI2TOaw98kdgpVlb6gMVmN2EWkzkdnwQDJhV+MFZob4wi+TpsDPv4fjubq
|
||||||
|
gqbM/MYc0kNtIEA4GkIJLCK5Hh7c6kCQfya+/eq4Ju6C3+I4R46/+9E7ixA83Zjf
|
||||||
|
ftqTlYOrlMby84Lvsf81LtiMiQKBgQDaFzXpDBPOIaup68k9NeZyXHKI8wNQXkui
|
||||||
|
JyjM9A3U2D8O9Yty8G+Oq0B4oUGlyenMGJiQmf3bAffJBkLCMXCGXYD8CCKsiSJ6
|
||||||
|
R6XBfbpPkzCwl67FFN/8Z0nxZ0lbxd2ZMTC4qxH4peD5TNZM89kTpSNXPrr55zzm
|
||||||
|
qREmxisZvwKBgQCNK3jBScjpkfFY1UdZkjFPXDBM5KQJBYGtztLIkNDIHGqnFsg9
|
||||||
|
R6QAp+b53GPyhWtxdK7jpCU+X7xXWwJD3AFq67sowFPJjD8Pn6Sc7IbuWf9ysSn5
|
||||||
|
rUihwXWr3yCk6tcclL0VjSjIPsB/SOf4XoNLV5is9J34Lzbyvr7JtwXryQKBgQCM
|
||||||
|
m3xRdUzrkD/J/M+w3ChoQPxDGVJgpXrj35Vplku4l3cIYPz4LNXvyK93VpgpmGVZ
|
||||||
|
Bd6PFAlcAwfLHnM6Gn/u0SgQ1fns/TkyVzEh77qIBWDV6eVvAQdsBvfgYPQl7Arz
|
||||||
|
8ofz969NfTzv3j8oO+sPxF9lp3cLGa/lEsmREyDEpwKBgQCvW+NK93oajo358gKh
|
||||||
|
/xfSv7yMiSL26NcIgHmQouZVXJ3Dg0KSISx8tgY0/7TwC2mPa0Ryhpb/3HtAIXoY
|
||||||
|
eqkQGHqnC4voxSoati667mMGdHL1+12WvQmhfTLCWmZ5ccNlR+aFD20TGbMxnejS
|
||||||
|
XnARctVkIcUYORcYwvuu9meDkw==
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
|
`
|
||||||
|
|
||||||
|
priv, err := PrivateKeyFromPKCS8PEM(pem)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
rt := priv.ToPKCS8PEM()
|
||||||
|
require.Equal(t, pem, rt)
|
||||||
|
}
|
||||||
181
crypto/rsa/private.go
Normal file
181
crypto/rsa/private.go
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
package rsa
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/pem"
|
||||||
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/INFURA/go-did/crypto"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ crypto.PrivateKeySigning = &PrivateKey{}
|
||||||
|
|
||||||
|
type PrivateKey struct {
|
||||||
|
k *rsa.PrivateKey
|
||||||
|
}
|
||||||
|
|
||||||
|
func PrivateKeyFromNEDPQ(n, e, d, p, q []byte) (*PrivateKey, error) {
|
||||||
|
pub, err := PublicKeyFromNE(n, e)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
dBInt := new(big.Int).SetBytes(d)
|
||||||
|
pBInt := new(big.Int).SetBytes(p)
|
||||||
|
qBInt := new(big.Int).SetBytes(q)
|
||||||
|
|
||||||
|
priv := &rsa.PrivateKey{
|
||||||
|
PublicKey: *pub.k,
|
||||||
|
D: dBInt,
|
||||||
|
Primes: []*big.Int{pBInt, qBInt},
|
||||||
|
}
|
||||||
|
|
||||||
|
// // while go doesn't care, we ensure to have the JWK canonical order of primes,
|
||||||
|
// // so that the JWK code becomes simpler
|
||||||
|
// if subtle.ConstantTimeCompare(p, q) > 0 {
|
||||||
|
// priv.Primes[0], priv.Primes[1] = priv.Primes[1], priv.Primes[0]
|
||||||
|
// }
|
||||||
|
|
||||||
|
err = priv.Validate()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
priv.Precompute()
|
||||||
|
|
||||||
|
return &PrivateKey{k: priv}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrivateKeyFromPKCS8DER decodes a PKCS#8 DER (binary) encoded private key.
|
||||||
|
func PrivateKeyFromPKCS8DER(bytes []byte) (*PrivateKey, error) {
|
||||||
|
priv, err := x509.ParsePKCS8PrivateKey(bytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rsaPriv := priv.(*rsa.PrivateKey)
|
||||||
|
return &PrivateKey{k: rsaPriv}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrivateKeyFromPKCS8PEM decodes an PKCS#8 PEM (string) encoded private key.
|
||||||
|
func PrivateKeyFromPKCS8PEM(str string) (*PrivateKey, error) {
|
||||||
|
block, _ := pem.Decode([]byte(str))
|
||||||
|
if block == nil {
|
||||||
|
return nil, fmt.Errorf("failed to decode PEM block")
|
||||||
|
}
|
||||||
|
if block.Type != pemPrivBlockType {
|
||||||
|
return nil, fmt.Errorf("incorrect PEM block type")
|
||||||
|
}
|
||||||
|
return PrivateKeyFromPKCS8DER(block.Bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PrivateKey) BitLen() int {
|
||||||
|
return p.k.N.BitLen()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PrivateKey) DBytes() []byte {
|
||||||
|
byteLength := (p.k.D.BitLen() + 7) / 8 // Round up to the nearest byte
|
||||||
|
buf := make([]byte, byteLength)
|
||||||
|
p.k.D.FillBytes(buf)
|
||||||
|
return buf
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PrivateKey) PBytes() []byte {
|
||||||
|
byteLength := (p.k.Primes[0].BitLen() + 7) / 8 // Round up to the nearest byte
|
||||||
|
buf := make([]byte, byteLength)
|
||||||
|
p.k.Primes[0].FillBytes(buf)
|
||||||
|
return buf
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PrivateKey) QBytes() []byte {
|
||||||
|
byteLength := (p.k.Primes[1].BitLen() + 7) / 8 // Round up to the nearest byte
|
||||||
|
buf := make([]byte, byteLength)
|
||||||
|
p.k.Primes[1].FillBytes(buf)
|
||||||
|
return buf
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PrivateKey) DpBytes() []byte {
|
||||||
|
if p.k.Precomputed.Dp == nil {
|
||||||
|
p.k.Precompute()
|
||||||
|
}
|
||||||
|
byteLength := (p.k.Precomputed.Dp.BitLen() + 7) / 8 // Round up to the nearest byte
|
||||||
|
buf := make([]byte, byteLength)
|
||||||
|
p.k.Precomputed.Dp.FillBytes(buf)
|
||||||
|
return buf
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PrivateKey) DqBytes() []byte {
|
||||||
|
if p.k.Precomputed.Dq == nil {
|
||||||
|
p.k.Precompute()
|
||||||
|
}
|
||||||
|
byteLength := (p.k.Precomputed.Dq.BitLen() + 7) / 8 // Round up to the nearest byte
|
||||||
|
buf := make([]byte, byteLength)
|
||||||
|
p.k.Precomputed.Dq.FillBytes(buf)
|
||||||
|
return buf
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PrivateKey) QiBytes() []byte {
|
||||||
|
if p.k.Precomputed.Qinv == nil {
|
||||||
|
p.k.Precompute()
|
||||||
|
}
|
||||||
|
byteLength := (p.k.Precomputed.Qinv.BitLen() + 7) / 8 // Round up to the nearest byte
|
||||||
|
buf := make([]byte, byteLength)
|
||||||
|
p.k.Precomputed.Qinv.FillBytes(buf)
|
||||||
|
return buf
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PrivateKey) Equal(other crypto.PrivateKey) bool {
|
||||||
|
if other, ok := other.(*PrivateKey); ok {
|
||||||
|
return p.k.Equal(other.k)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PrivateKey) Public() crypto.PublicKey {
|
||||||
|
rsaPub := p.k.Public().(*rsa.PublicKey)
|
||||||
|
return &PublicKey{k: rsaPub}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PrivateKey) ToPKCS8DER() []byte {
|
||||||
|
res, _ := x509.MarshalPKCS8PrivateKey(p.k)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PrivateKey) ToPKCS8PEM() string {
|
||||||
|
der := p.ToPKCS8DER()
|
||||||
|
return string(pem.EncodeToMemory(&pem.Block{
|
||||||
|
Type: pemPrivBlockType,
|
||||||
|
Bytes: der,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PrivateKey) SignToBytes(message []byte, opts ...crypto.SigningOption) ([]byte, error) {
|
||||||
|
return nil, fmt.Errorf("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PrivateKey) SignToASN1(message []byte, opts ...crypto.SigningOption) ([]byte, error) {
|
||||||
|
return nil, fmt.Errorf("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// func (p *PrivateKey) PublicKeyIsCompatible(remote crypto.PublicKey) bool {
|
||||||
|
// if _, ok := remote.(*PublicKey); ok {
|
||||||
|
// return true
|
||||||
|
// }
|
||||||
|
// return false
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// func (p *PrivateKey) KeyExchange(remote crypto.PublicKey) ([]byte, error) {
|
||||||
|
// if remote, ok := remote.(*PublicKey); ok {
|
||||||
|
// // First, we need to convert the ECDSA (signing only) to the equivalent ECDH keys
|
||||||
|
// ecdhPriv, err := p.k.ECDH()
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
// ecdhPub, err := remote.k.ECDH()
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return ecdhPriv.ECDH(ecdhPub)
|
||||||
|
// }
|
||||||
|
// return nil, fmt.Errorf("incompatible public key")
|
||||||
|
// }
|
||||||
134
crypto/rsa/public.go
Normal file
134
crypto/rsa/public.go
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
package rsa
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/pem"
|
||||||
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/INFURA/go-did/crypto"
|
||||||
|
helpers "github.com/INFURA/go-did/crypto/internal"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ crypto.PublicKeySigning = &PublicKey{}
|
||||||
|
|
||||||
|
type PublicKey struct {
|
||||||
|
k *rsa.PublicKey
|
||||||
|
}
|
||||||
|
|
||||||
|
func PublicKeyFromPKCS1DER(bytes []byte) (*PublicKey, error) {
|
||||||
|
pub, err := x509.ParsePKCS1PublicKey(bytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &PublicKey{k: pub}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func PublicKeyFromNE(n, e []byte) (*PublicKey, error) {
|
||||||
|
nBInt := new(big.Int).SetBytes(n)
|
||||||
|
// some basic checks
|
||||||
|
if nBInt.Sign() <= 0 {
|
||||||
|
return nil, fmt.Errorf("invalid modulus")
|
||||||
|
}
|
||||||
|
if nBInt.BitLen() < MinRsaKeyBits {
|
||||||
|
return nil, fmt.Errorf("key length too small")
|
||||||
|
}
|
||||||
|
if nBInt.BitLen() > MaxRsaKeyBits {
|
||||||
|
return nil, fmt.Errorf("key length too large")
|
||||||
|
}
|
||||||
|
if nBInt.Bit(0) == 0 {
|
||||||
|
return nil, fmt.Errorf("modulus must be odd")
|
||||||
|
}
|
||||||
|
|
||||||
|
eBInt := new(big.Int).SetBytes(e)
|
||||||
|
// some basic checks
|
||||||
|
if !eBInt.IsInt64() {
|
||||||
|
return nil, fmt.Errorf("invalid exponent")
|
||||||
|
}
|
||||||
|
if eBInt.Sign() <= 0 {
|
||||||
|
return nil, fmt.Errorf("exponent must be positive")
|
||||||
|
}
|
||||||
|
if eBInt.Bit(0) == 0 {
|
||||||
|
return nil, fmt.Errorf("exponent must be odd")
|
||||||
|
}
|
||||||
|
return &PublicKey{k: &rsa.PublicKey{N: nBInt, E: int(eBInt.Int64())}}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PublicKeyFromPublicKeyMultibase decodes the public key from its Multibase form
|
||||||
|
func PublicKeyFromPublicKeyMultibase(multibase string) (*PublicKey, error) {
|
||||||
|
code, bytes, err := helpers.PublicKeyMultibaseDecode(multibase)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if code != MultibaseCode {
|
||||||
|
return nil, fmt.Errorf("invalid code")
|
||||||
|
}
|
||||||
|
return PublicKeyFromX509DER(bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PublicKeyFromX509DER decodes an X.509 DER (binary) encoded public key.
|
||||||
|
func PublicKeyFromX509DER(bytes []byte) (*PublicKey, error) {
|
||||||
|
pub, err := x509.ParsePKIXPublicKey(bytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &PublicKey{k: pub.(*rsa.PublicKey)}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PublicKeyFromX509PEM decodes an X.509 PEM (string) encoded public key.
|
||||||
|
func PublicKeyFromX509PEM(str string) (*PublicKey, error) {
|
||||||
|
block, _ := pem.Decode([]byte(str))
|
||||||
|
if block == nil {
|
||||||
|
return nil, fmt.Errorf("failed to decode PEM block")
|
||||||
|
}
|
||||||
|
if block.Type != pemPubBlockType {
|
||||||
|
return nil, fmt.Errorf("incorrect PEM block type")
|
||||||
|
}
|
||||||
|
return PublicKeyFromX509DER(block.Bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PublicKey) BitLen() int {
|
||||||
|
return p.k.N.BitLen()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PublicKey) NBytes() []byte {
|
||||||
|
return p.k.N.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PublicKey) EBytes() []byte {
|
||||||
|
return new(big.Int).SetInt64(int64(p.k.E)).Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PublicKey) Equal(other crypto.PublicKey) bool {
|
||||||
|
if other, ok := other.(*PublicKey); ok {
|
||||||
|
return p.k.Equal(other.k)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PublicKey) ToPublicKeyMultibase() string {
|
||||||
|
bytes := p.ToX509DER()
|
||||||
|
return helpers.PublicKeyMultibaseEncode(MultibaseCode, bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PublicKey) ToX509DER() []byte {
|
||||||
|
res, _ := x509.MarshalPKIXPublicKey(p.k)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PublicKey) ToX509PEM() string {
|
||||||
|
der := p.ToX509DER()
|
||||||
|
return string(pem.EncodeToMemory(&pem.Block{
|
||||||
|
Type: pemPubBlockType,
|
||||||
|
Bytes: der,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PublicKey) VerifyBytes(message, signature []byte, opts ...crypto.SigningOption) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PublicKey) VerifyASN1(message, signature []byte, opts ...crypto.SigningOption) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user