github.com/coyove/sdss@v0.0.0-20231129015646-c2ec58cca6a2/contrib/skip32/skip32.go (about) 1 // Copyright (c) 2012 Damian Gryski <damian@gryski.com> 2 // Licensed under MIT 3 4 // Package skip32 implements the Skip32 blockcipher 5 /* 6 SKIP32 is a 32-bit block cipher based on SKIPJACK, written by Greg Rose of QUALCOMM Australia. 7 It is useful for obfuscating small integers (like sequential database ids) 8 that are exposed to prevent an analysis of growth rates as in: 9 https://en.wikipedia.org/wiki/German_tank_problem 10 This library deliberately exposes only the integer obfuscation routines and 11 hides the low-level encryption. 12 Using this routine to hide IDs is not sufficient security by itself. Please 13 ensure your application does secondary validation and do not rely on the 14 secrecy of the generated IDs. 15 */ 16 package skip32 17 18 import ( 19 "unsafe" 20 ) 21 22 var ftable = [...]byte{ 23 0xa3, 0xd7, 0x09, 0x83, 0xf8, 0x48, 0xf6, 0xf4, 0xb3, 0x21, 0x15, 0x78, 0x99, 0xb1, 0xaf, 0xf9, 24 0xe7, 0x2d, 0x4d, 0x8a, 0xce, 0x4c, 0xca, 0x2e, 0x52, 0x95, 0xd9, 0x1e, 0x4e, 0x38, 0x44, 0x28, 25 0x0a, 0xdf, 0x02, 0xa0, 0x17, 0xf1, 0x60, 0x68, 0x12, 0xb7, 0x7a, 0xc3, 0xe9, 0xfa, 0x3d, 0x53, 26 0x96, 0x84, 0x6b, 0xba, 0xf2, 0x63, 0x9a, 0x19, 0x7c, 0xae, 0xe5, 0xf5, 0xf7, 0x16, 0x6a, 0xa2, 27 0x39, 0xb6, 0x7b, 0x0f, 0xc1, 0x93, 0x81, 0x1b, 0xee, 0xb4, 0x1a, 0xea, 0xd0, 0x91, 0x2f, 0xb8, 28 0x55, 0xb9, 0xda, 0x85, 0x3f, 0x41, 0xbf, 0xe0, 0x5a, 0x58, 0x80, 0x5f, 0x66, 0x0b, 0xd8, 0x90, 29 0x35, 0xd5, 0xc0, 0xa7, 0x33, 0x06, 0x65, 0x69, 0x45, 0x00, 0x94, 0x56, 0x6d, 0x98, 0x9b, 0x76, 30 0x97, 0xfc, 0xb2, 0xc2, 0xb0, 0xfe, 0xdb, 0x20, 0xe1, 0xeb, 0xd6, 0xe4, 0xdd, 0x47, 0x4a, 0x1d, 31 0x42, 0xed, 0x9e, 0x6e, 0x49, 0x3c, 0xcd, 0x43, 0x27, 0xd2, 0x07, 0xd4, 0xde, 0xc7, 0x67, 0x18, 32 0x89, 0xcb, 0x30, 0x1f, 0x8d, 0xc6, 0x8f, 0xaa, 0xc8, 0x74, 0xdc, 0xc9, 0x5d, 0x5c, 0x31, 0xa4, 33 0x70, 0x88, 0x61, 0x2c, 0x9f, 0x0d, 0x2b, 0x87, 0x50, 0x82, 0x54, 0x64, 0x26, 0x7d, 0x03, 0x40, 34 0x34, 0x4b, 0x1c, 0x73, 0xd1, 0xc4, 0xfd, 0x3b, 0xcc, 0xfb, 0x7f, 0xab, 0xe6, 0x3e, 0x5b, 0xa5, 35 0xad, 0x04, 0x23, 0x9c, 0x14, 0x51, 0x22, 0xf0, 0x29, 0x79, 0x71, 0x7e, 0xff, 0x8c, 0x0e, 0xe2, 36 0x0c, 0xef, 0xbc, 0x72, 0x75, 0x6f, 0x37, 0xa1, 0xec, 0xd3, 0x8e, 0x62, 0x8b, 0x86, 0x10, 0xe8, 37 0x08, 0x77, 0x11, 0xbe, 0x92, 0x4f, 0x24, 0xc5, 0x32, 0x36, 0x9d, 0xcf, 0xf3, 0xa6, 0xbb, 0xac, 38 0x5e, 0x6c, 0xa9, 0x13, 0x57, 0x25, 0xb5, 0xe3, 0xbd, 0xa8, 0x3a, 0x01, 0x05, 0x59, 0x2a, 0x46, 39 } 40 41 func g(key [10]byte, k int, w uint16) uint16 { 42 43 g1 := byte((w >> 8) & 0xff) 44 g2 := byte(w & 0xff) 45 46 g3 := ftable[g2^key[(4*k+0)%10]] ^ g1 47 g4 := ftable[g3^key[(4*k+1)%10]] ^ g2 48 g5 := ftable[g4^key[(4*k+2)%10]] ^ g3 49 g6 := ftable[g5^key[(4*k+3)%10]] ^ g4 50 51 return (uint16(g5) << 8) + uint16(g6) 52 } 53 54 func crypt32(key [10]byte, buf uint32, encrypt bool) uint32 { 55 var kstep, k int 56 57 if encrypt { 58 kstep = 1 59 k = 0 60 } else { 61 kstep = -1 62 k = 23 63 } 64 65 /* pack into words */ 66 wl := uint16(buf >> 16) 67 wr := uint16(buf) 68 69 /* 24 feistel rounds, doubled up */ 70 for i := 0; i < 24/2; i++ { 71 wr ^= g(key, k, wl) ^ uint16(k) 72 k += kstep 73 wl ^= g(key, k, wr) ^ uint16(k) 74 k += kstep 75 } 76 77 /* implicitly swap halves while unpacking */ 78 return uint32(byte(wr>>8))<<24 | 79 uint32(byte(wr&0xFF))<<16 | 80 uint32(byte(wl>>8))<<8 | 81 uint32(byte(wl&0xFF)) 82 } 83 84 // Skip32 is a 32-bit integer obfuscator 85 type Skip32 [10]byte 86 87 func (s Skip32) Encrypt(id uint32) uint32 { 88 return crypt32(s, id, true /* encrypt */) 89 } 90 91 func (s Skip32) EncryptBytes(buf []byte) { 92 id := (*uint32)(unsafe.Pointer(&buf[0])) 93 *id = crypt32(s, *id, true /* encrypt */) 94 } 95 96 func (s Skip32) Decrypt(id uint32) uint32 { 97 return crypt32(s, id, false /* decrypt */) 98 } 99 100 func (s Skip32) DecryptBytes(buf []byte) { 101 id := (*uint32)(unsafe.Pointer(&buf[0])) 102 *id = crypt32(s, *id, false) 103 } 104 105 func ReadSkip32Key(v string) (s Skip32) { 106 copy(s[:], v) 107 return 108 }