mirror of
https://github.com/emmansun/gmsm.git
synced 2025-04-26 12:16:20 +08:00
remove non-shangmi alg
This commit is contained in:
parent
0a827de266
commit
88dc7dc8ec
@ -1,46 +0,0 @@
|
||||
// Package rc5 handle rc5 symmetric encryption algorithm
|
||||
package rc5
|
||||
|
||||
import (
|
||||
"crypto/cipher"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Reference: https://en.wikipedia.org/wiki/RC5
|
||||
// http://people.csail.mit.edu/rivest/Rivest-rc5rev.pdf
|
||||
|
||||
// NewCipher creates and returns a new cipher.Block.
|
||||
// The key argument should be the RC5 key, the wordSize arguement should be word size in bits,
|
||||
// the r argument should be number of rounds.
|
||||
func NewCipher(key []byte, wordSize, r uint) (cipher.Block, error) {
|
||||
k := len(key)
|
||||
switch k {
|
||||
default:
|
||||
return nil, fmt.Errorf("rc5: invalid key size %d, we support 16/24/32 now", k)
|
||||
case 16, 24, 32:
|
||||
break
|
||||
}
|
||||
if r < 8 || r > 127 {
|
||||
return nil, fmt.Errorf("rc5: invalid rounds %d, should be between 8 and 127", r)
|
||||
}
|
||||
switch wordSize {
|
||||
case 32:
|
||||
return newCipher32(key, r)
|
||||
case 64:
|
||||
return newCipher64(key, r)
|
||||
default:
|
||||
return nil, fmt.Errorf("rc5: unsupported word size %d, support 32/64 now", wordSize)
|
||||
}
|
||||
}
|
||||
|
||||
// NewCipher32 creates and returns a new cipher.Block with 32 bits word size.
|
||||
// The key argument should be the RC5 key, the r argument should be number of rounds.
|
||||
func NewCipher32(key []byte, r uint) (cipher.Block, error) {
|
||||
return NewCipher(key, 32, r)
|
||||
}
|
||||
|
||||
// NewCipher64 creates and returns a new cipher.Block with 64 bits word size.
|
||||
// The key argument should be the RC5 key, the r argument should be number of rounds.
|
||||
func NewCipher64(key []byte, r uint) (cipher.Block, error) {
|
||||
return NewCipher(key, 64, r)
|
||||
}
|
101
rc5/cipher32.go
101
rc5/cipher32.go
@ -1,101 +0,0 @@
|
||||
package rc5
|
||||
|
||||
import (
|
||||
"crypto/cipher"
|
||||
"encoding/binary"
|
||||
"math/bits"
|
||||
|
||||
"github.com/emmansun/gmsm/internal/subtle"
|
||||
)
|
||||
|
||||
const (
|
||||
// BlockSize the RC5/32 block size in bytes.
|
||||
BlockSize32 = 8
|
||||
P32 = 0xB7E15163
|
||||
Q32 = 0x9E3779B9
|
||||
)
|
||||
|
||||
type rc5Cipher32 struct {
|
||||
rounds uint
|
||||
rk []uint32
|
||||
}
|
||||
|
||||
func newCipher32(key []byte, rounds uint) (cipher.Block, error) {
|
||||
c := &rc5Cipher32{}
|
||||
c.rounds = rounds
|
||||
c.rk = make([]uint32, (rounds+1)<<1)
|
||||
expandKey32(key, c.rk)
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func expandKey32(key []byte, rk []uint32) {
|
||||
roundKeys := len(rk)
|
||||
// L is initially a c-length list of 0-valued w-length words
|
||||
L := make([]uint32, len(key)/4)
|
||||
lenL := len(L)
|
||||
for i := 0; i < lenL; i++ {
|
||||
L[i] = binary.LittleEndian.Uint32(key[:4])
|
||||
key = key[4:]
|
||||
}
|
||||
// Initialize key-independent pseudorandom S array
|
||||
// S is initially a t=2(r+1) length list of undefined w-length words
|
||||
rk[0] = P32
|
||||
for i := 1; i < roundKeys; i++ {
|
||||
rk[i] = rk[i-1] + Q32
|
||||
}
|
||||
// The main key scheduling loop
|
||||
var A uint32
|
||||
var B uint32
|
||||
var i, j int
|
||||
for k := 0; k < 3*roundKeys; k++ {
|
||||
rk[i] = bits.RotateLeft32(rk[i]+(A+B), 3)
|
||||
A = rk[i]
|
||||
L[j] = bits.RotateLeft32(L[j]+(A+B), int(A+B))
|
||||
B = L[j]
|
||||
i = (i + 1) % roundKeys
|
||||
j = (j + 1) % lenL
|
||||
}
|
||||
}
|
||||
|
||||
func (c *rc5Cipher32) BlockSize() int { return BlockSize32 }
|
||||
|
||||
func (c *rc5Cipher32) Encrypt(dst, src []byte) {
|
||||
if len(src) < BlockSize32 {
|
||||
panic("rc5-32: input not full block")
|
||||
}
|
||||
if len(dst) < BlockSize32 {
|
||||
panic("rc5-32: output not full block")
|
||||
}
|
||||
if subtle.InexactOverlap(dst[:BlockSize32], src[:BlockSize32]) {
|
||||
panic("rc5-32: invalid buffer overlap")
|
||||
}
|
||||
A := binary.LittleEndian.Uint32(src[:4]) + c.rk[0]
|
||||
B := binary.LittleEndian.Uint32(src[4:BlockSize32]) + c.rk[1]
|
||||
|
||||
for r := 1; r <= int(c.rounds); r++ {
|
||||
A = bits.RotateLeft32(A^B, int(B)) + c.rk[r<<1]
|
||||
B = bits.RotateLeft32(B^A, int(A)) + c.rk[r<<1+1]
|
||||
}
|
||||
binary.LittleEndian.PutUint32(dst[:4], A)
|
||||
binary.LittleEndian.PutUint32(dst[4:8], B)
|
||||
}
|
||||
|
||||
func (c *rc5Cipher32) Decrypt(dst, src []byte) {
|
||||
if len(src) < BlockSize32 {
|
||||
panic("rc5-32: input not full block")
|
||||
}
|
||||
if len(dst) < BlockSize32 {
|
||||
panic("rc5-32: output not full block")
|
||||
}
|
||||
if subtle.InexactOverlap(dst[:BlockSize32], src[:BlockSize32]) {
|
||||
panic("rc5-32: invalid buffer overlap")
|
||||
}
|
||||
A := binary.LittleEndian.Uint32(src[:4])
|
||||
B := binary.LittleEndian.Uint32(src[4:8])
|
||||
for r := c.rounds; r >= 1; r-- {
|
||||
B = A ^ bits.RotateLeft32(B-c.rk[r<<1+1], -int(A))
|
||||
A = B ^ bits.RotateLeft32(A-c.rk[r<<1], -int(B))
|
||||
}
|
||||
binary.LittleEndian.PutUint32(dst[:4], A-c.rk[0])
|
||||
binary.LittleEndian.PutUint32(dst[4:8], B-c.rk[1])
|
||||
}
|
@ -1,93 +0,0 @@
|
||||
package rc5
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type Crypt32Test struct {
|
||||
key string
|
||||
in string
|
||||
out string
|
||||
}
|
||||
|
||||
// http://people.csail.mit.edu/rivest/Rivest-rc5rev.pdf
|
||||
// RC5-32/12/16
|
||||
var encrypt32Tests = []Crypt32Test{
|
||||
{
|
||||
"00000000000000000000000000000000",
|
||||
"0000000000000000",
|
||||
"21A5DBEE154B8F6D",
|
||||
},
|
||||
{
|
||||
"915F4619BE41B2516355A50110A9CE91",
|
||||
"21A5DBEE154B8F6D",
|
||||
"F7C013AC5B2B8952",
|
||||
},
|
||||
{
|
||||
"783348E75AEB0F2FD7B169BB8DC16787",
|
||||
"F7C013AC5B2B8952",
|
||||
"2F42B3B70369FC92",
|
||||
},
|
||||
{
|
||||
"DC49DB1375A5584F6485B413B5F12BAF",
|
||||
"2F42B3B70369FC92",
|
||||
"65C178B284D197CC",
|
||||
},
|
||||
{
|
||||
"5269F149D41BA0152497574D7F153125",
|
||||
"65C178B284D197CC",
|
||||
"EB44E415DA319824",
|
||||
},
|
||||
}
|
||||
|
||||
func Test_rc5Cipher32_Encrypt(t *testing.T) {
|
||||
for _, test := range encrypt32Tests {
|
||||
key, _ := hex.DecodeString(test.key)
|
||||
in, _ := hex.DecodeString(test.in)
|
||||
target, _ := hex.DecodeString(test.out)
|
||||
out := make([]byte, 8)
|
||||
dst := make([]byte, 8)
|
||||
c, err := NewCipher32(key, 12)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
c.Encrypt(out, in)
|
||||
if !reflect.DeepEqual(out, target) {
|
||||
t.Errorf("expected=%v, result=%v\n", test.out, strings.ToUpper(hex.EncodeToString(out)))
|
||||
}
|
||||
c.Decrypt(dst, out)
|
||||
if !reflect.DeepEqual(dst, in) {
|
||||
t.Errorf("expected=%v, result=%v\n", test.in, strings.ToUpper(hex.EncodeToString(dst)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://tools.ietf.org/id/draft-krovetz-rc6-rc5-vectors-00.html#rfc.section.4
|
||||
func Test_RC5_322016(t *testing.T) {
|
||||
testData := &Crypt32Test{
|
||||
"000102030405060708090A0B0C0D0E0F",
|
||||
"0001020304050607",
|
||||
"2A0EDC0E9431FF73",
|
||||
}
|
||||
key, _ := hex.DecodeString(testData.key)
|
||||
in, _ := hex.DecodeString(testData.in)
|
||||
target, _ := hex.DecodeString(testData.out)
|
||||
out := make([]byte, 8)
|
||||
dst := make([]byte, 8)
|
||||
c, err := NewCipher32(key, 20)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
c.Encrypt(out, in)
|
||||
if !reflect.DeepEqual(out, target) {
|
||||
t.Errorf("expected=%v, result=%v\n", testData.out, strings.ToUpper(hex.EncodeToString(out)))
|
||||
}
|
||||
c.Decrypt(dst, out)
|
||||
if !reflect.DeepEqual(dst, in) {
|
||||
t.Errorf("expected=%v, result=%v\n", testData.in, strings.ToUpper(hex.EncodeToString(dst)))
|
||||
}
|
||||
}
|
101
rc5/cipher64.go
101
rc5/cipher64.go
@ -1,101 +0,0 @@
|
||||
package rc5
|
||||
|
||||
import (
|
||||
"crypto/cipher"
|
||||
"encoding/binary"
|
||||
"math/bits"
|
||||
|
||||
"github.com/emmansun/gmsm/internal/subtle"
|
||||
)
|
||||
|
||||
const (
|
||||
// BlockSize the RC5/64 block size in bytes.
|
||||
BlockSize64 = 16
|
||||
P64 = 0xB7E151628AED2A6B
|
||||
Q64 = 0x9E3779B97F4A7C15
|
||||
)
|
||||
|
||||
type rc5Cipher64 struct {
|
||||
rounds uint
|
||||
rk []uint64
|
||||
}
|
||||
|
||||
func newCipher64(key []byte, rounds uint) (cipher.Block, error) {
|
||||
c := &rc5Cipher64{}
|
||||
c.rounds = rounds
|
||||
c.rk = make([]uint64, (rounds+1)<<1)
|
||||
expandKey64(key, c.rk)
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func expandKey64(key []byte, rk []uint64) {
|
||||
roundKeys := len(rk)
|
||||
// L is initially a c-length list of 0-valued w-length words
|
||||
L := make([]uint64, len(key)/8)
|
||||
lenL := len(L)
|
||||
for i := 0; i < lenL; i++ {
|
||||
L[i] = binary.LittleEndian.Uint64(key[:8])
|
||||
key = key[8:]
|
||||
}
|
||||
// Initialize key-independent pseudorandom S array
|
||||
// S is initially a t=2(r+1) length list of undefined w-length words
|
||||
rk[0] = P64
|
||||
for i := 1; i < roundKeys; i++ {
|
||||
rk[i] = rk[i-1] + Q64
|
||||
}
|
||||
// The main key scheduling loop
|
||||
var A uint64
|
||||
var B uint64
|
||||
var i, j int
|
||||
for k := 0; k < 3*roundKeys; k++ {
|
||||
rk[i] = bits.RotateLeft64(rk[i]+(A+B), 3)
|
||||
A = rk[i]
|
||||
L[j] = bits.RotateLeft64(L[j]+(A+B), int(A+B))
|
||||
B = L[j]
|
||||
i = (i + 1) % roundKeys
|
||||
j = (j + 1) % lenL
|
||||
}
|
||||
}
|
||||
|
||||
func (c *rc5Cipher64) BlockSize() int { return BlockSize64 }
|
||||
|
||||
func (c *rc5Cipher64) Encrypt(dst, src []byte) {
|
||||
if len(src) < BlockSize64 {
|
||||
panic("rc5-64: input not full block")
|
||||
}
|
||||
if len(dst) < BlockSize64 {
|
||||
panic("rc5-64: output not full block")
|
||||
}
|
||||
if subtle.InexactOverlap(dst[:BlockSize64], src[:BlockSize64]) {
|
||||
panic("rc5-64: invalid buffer overlap")
|
||||
}
|
||||
A := binary.LittleEndian.Uint64(src[:8]) + c.rk[0]
|
||||
B := binary.LittleEndian.Uint64(src[8:BlockSize64]) + c.rk[1]
|
||||
|
||||
for r := 1; r <= int(c.rounds); r++ {
|
||||
A = bits.RotateLeft64(A^B, int(B)) + c.rk[r<<1]
|
||||
B = bits.RotateLeft64(B^A, int(A)) + c.rk[r<<1+1]
|
||||
}
|
||||
binary.LittleEndian.PutUint64(dst[:8], A)
|
||||
binary.LittleEndian.PutUint64(dst[8:16], B)
|
||||
}
|
||||
|
||||
func (c *rc5Cipher64) Decrypt(dst, src []byte) {
|
||||
if len(src) < BlockSize64 {
|
||||
panic("rc5-64: input not full block")
|
||||
}
|
||||
if len(dst) < BlockSize64 {
|
||||
panic("rc5-64: output not full block")
|
||||
}
|
||||
if subtle.InexactOverlap(dst[:BlockSize64], src[:BlockSize64]) {
|
||||
panic("rc5-64: invalid buffer overlap")
|
||||
}
|
||||
A := binary.LittleEndian.Uint64(src[:8])
|
||||
B := binary.LittleEndian.Uint64(src[8:16])
|
||||
for r := c.rounds; r >= 1; r-- {
|
||||
B = A ^ bits.RotateLeft64(B-c.rk[r<<1+1], -int(A))
|
||||
A = B ^ bits.RotateLeft64(A-c.rk[r<<1], -int(B))
|
||||
}
|
||||
binary.LittleEndian.PutUint64(dst[:8], A-c.rk[0])
|
||||
binary.LittleEndian.PutUint64(dst[8:16], B-c.rk[1])
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
package rc5
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// https://tools.ietf.org/id/draft-krovetz-rc6-rc5-vectors-00.html#rfc.section.4
|
||||
func Test_RC5_642424(t *testing.T) {
|
||||
testData := &Crypt32Test{
|
||||
"000102030405060708090A0B0C0D0E0F1011121314151617",
|
||||
"000102030405060708090A0B0C0D0E0F",
|
||||
"A46772820EDBCE0235ABEA32AE7178DA",
|
||||
}
|
||||
key, _ := hex.DecodeString(testData.key)
|
||||
in, _ := hex.DecodeString(testData.in)
|
||||
target, _ := hex.DecodeString(testData.out)
|
||||
out := make([]byte, 16)
|
||||
dst := make([]byte, 16)
|
||||
c, err := NewCipher64(key, 24)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
c.Encrypt(out, in)
|
||||
if !reflect.DeepEqual(out, target) {
|
||||
t.Errorf("expected=%v, result=%v\n", testData.out, strings.ToUpper(hex.EncodeToString(out)))
|
||||
}
|
||||
c.Decrypt(dst, out)
|
||||
if !reflect.DeepEqual(dst, in) {
|
||||
t.Errorf("expected=%v, result=%v\n", testData.in, strings.ToUpper(hex.EncodeToString(dst)))
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user