Skip to content

Commit 6a4eda8

Browse files
committed
added sha-0 support
1 parent 71f9da2 commit 6a4eda8

File tree

2 files changed

+193
-0
lines changed

2 files changed

+193
-0
lines changed

sha.go

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Copyright (C) 2014 Space Monkey, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// +build cgo
16+
17+
package openssl
18+
19+
/*
20+
#include <errno.h>
21+
#include <stdio.h>
22+
#include <stdlib.h>
23+
#include <unistd.h>
24+
25+
#include "openssl/evp.h"
26+
*/
27+
import "C"
28+
29+
import (
30+
"errors"
31+
"runtime"
32+
"unsafe"
33+
)
34+
35+
type SHAHash struct {
36+
ctx C.EVP_MD_CTX
37+
engine *Engine
38+
}
39+
40+
func NewSHAHash() (*SHAHash, error) { return NewSHAHashWithEngine(nil) }
41+
42+
func NewSHAHashWithEngine(e *Engine) (*SHAHash, error) {
43+
hash := &SHAHash{engine: e}
44+
C.EVP_MD_CTX_init(&hash.ctx)
45+
runtime.SetFinalizer(hash, func(hash *SHAHash) { hash.Close() })
46+
if err := hash.Reset(); err != nil {
47+
return nil, err
48+
}
49+
return hash, nil
50+
}
51+
52+
func (s *SHAHash) Close() {
53+
C.EVP_MD_CTX_cleanup(&s.ctx)
54+
}
55+
56+
func (s *SHAHash) Reset() error {
57+
if 1 != C.EVP_DigestInit_ex(&s.ctx, C.EVP_sha(), engineRef(s.engine)) {
58+
return errors.New("openssl: sha: cannot init digest ctx")
59+
}
60+
return nil
61+
}
62+
63+
func (s *SHAHash) Write(p []byte) (n int, err error) {
64+
if len(p) == 0 {
65+
return 0, nil
66+
}
67+
if 1 != C.EVP_DigestUpdate(&s.ctx, unsafe.Pointer(&p[0]),
68+
C.size_t(len(p))) {
69+
return 0, errors.New("openssl: sha: cannot update digest")
70+
}
71+
return len(p), nil
72+
}
73+
74+
func (s *SHAHash) Sum() (result [20]byte, err error) {
75+
if 1 != C.EVP_DigestFinal_ex(&s.ctx,
76+
(*C.uchar)(unsafe.Pointer(&result[0])), nil) {
77+
return result, errors.New("openssl: sha: cannot finalize ctx")
78+
}
79+
return result, s.Reset()
80+
}
81+
82+
func SHA(data []byte) (result [20]byte, err error) {
83+
hash, err := NewSHAHash()
84+
if err != nil {
85+
return result, err
86+
}
87+
defer hash.Close()
88+
if _, err := hash.Write(data); err != nil {
89+
return result, err
90+
}
91+
return hash.Sum()
92+
}

sha_test.go

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// Copyright (C) 2014 Space Monkey, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// +build cgo
16+
17+
package openssl
18+
19+
import (
20+
"crypto/rand"
21+
"fmt"
22+
"io"
23+
"testing"
24+
)
25+
26+
type shaTest struct {
27+
out string
28+
in string
29+
}
30+
31+
var golden = []shaTest{
32+
{"f96cea198ad1dd5617ac084a3d92c6107708c0ef", ""},
33+
{"37f297772fae4cb1ba39b6cf9cf0381180bd62f2", "a"},
34+
{"488373d362684af3d3f7a6a408b59dfe85419e09", "ab"},
35+
{"0164b8a914cd2a5e74c4f7ff082c4d97f1edf880", "abc"},
36+
{"082c73b06f71185d840fb4b28eb3abade67714bc", "abcd"},
37+
{"d624e34951bb800f0acae773001df8cffe781ba8", "abcde"},
38+
{"2a589f7750598dc0ea0a608719e04327f609279a", "abcdef"},
39+
{"5bdf01f9298e9d19d3f8d15520fd74eed600b497", "abcdefg"},
40+
{"734ba8b31975d0dbae4d6e249f4e8da270796c94", "abcdefgh"},
41+
{"e85c35055b093f7b9948898d2e7fbaf13b7ed3b4", "abcdefghi"},
42+
{"ac2f1f843ebb6805940ae2da76b62d11ce0c2dfb", "abcdefghij"},
43+
{"43f87ce8207df8464ec94df98c6de614259f9f9b", "Discard medicine more than two years old."},
44+
{"556a4b84a7aae18d533c490cc6166bceeadb1e78", "He who has a shady past knows that nice guys finish last."},
45+
{"154c149aebd6c69113a831b410d677aef75d8c16", "I wouldn't marry him with a ten foot pole."},
46+
{"030c1ac6c94babda05f15127ef25455a090de6d8", "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave"},
47+
{"66f72cd3e3102a22d9921f92e1080816cc6829a6", "The days of the digital watch are numbered. -Tom Stoppard"},
48+
{"519d3b4cbaba8d214d955bcc1b6af0f9f8d4a73a", "Nepal premier won't resign."},
49+
{"a633be186221a0a6715e0cb7f170c2be6a595434", "For every action there is an equal and opposite government program."},
50+
{"0255fc603ab48b6f9df88990f78262359e641621", "His money is twice tainted: 'taint yours and 'taint mine."},
51+
{"693919e639922d0b8242115512ec5cc904758fbc", "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977"},
52+
{"17e56ae76e612337ad7b634aa839271d60beda96", "It's a tiny change to the code and not completely disgusting. - Bob Manchek"},
53+
{"9d3d0f7017181467bc453dbb83b676ea27291604", "size: a.out: bad magic"},
54+
{"1cc69323cc1a8523a672372c8dc076d6d2f64381", "The major problem is with sendmail. -Mark Horton"},
55+
{"acd8d33701fc3e776ca7113e83917f87185f01a0", "Give me a rock, paper and scissors and I will move the world. CCFestoon"},
56+
{"8803803ded9426a430761e54addc38e4541f729e", "If the enemy is within range, then so are you."},
57+
{"e8875d30c04df24335db4a989c5ac5de295a932b", "It's well we cannot hear the screams/That we create in others' dreams."},
58+
{"6ce8c4a10827943b88f0fc00fb075129236c3100", "You remind me of a TV show, but that's all right: I watch it anyway."},
59+
{"941a49d51f52c2e55a54de58f49787605e6572aa", "C is as portable as Stonehedge!!"},
60+
{"34af7a6ff354b6d0bce0a09af0984ccae2a0d14c", "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley"},
61+
{"2398df93efff72e5a041c092b13b81844b196c28", "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction. Lewis-Randall Rule"},
62+
{"7dda7376c190859ad60e072139fc1028171aab4b", "How can you write a big system without C++? -Paul Glick"},
63+
}
64+
65+
func TestSHA(t *testing.T) {
66+
for _, g := range golden {
67+
got, err := SHA([]byte(g.in))
68+
if err != nil {
69+
t.Fatal(err)
70+
}
71+
72+
s := fmt.Sprintf("%x", got)
73+
if s != g.out {
74+
t.Fatalf("Sum function: sha(%s) = %s want %s", g.in, s, g.out)
75+
}
76+
}
77+
}
78+
79+
func benchmarkSHA(b *testing.B, length int64) {
80+
buf := make([]byte, length)
81+
if _, err := io.ReadFull(rand.Reader, buf); err != nil {
82+
b.Fatal(err)
83+
}
84+
b.SetBytes(length)
85+
b.ResetTimer()
86+
for i := 0; i < b.N; i++ {
87+
SHA(buf)
88+
}
89+
}
90+
91+
func BenchmarkSHALarge(b *testing.B) {
92+
benchmarkSHA(b, 1024*1024)
93+
}
94+
95+
func BenchmarkSHAMedium(b *testing.B) {
96+
benchmarkSHA(b, 1024)
97+
}
98+
99+
func BenchmarkSHASmall(b *testing.B) {
100+
benchmarkSHA(b, 1)
101+
}

0 commit comments

Comments
 (0)