// build 2^w keys, each having a unique value in the first w bits func (s *XLSuite) makePermutedKeys(rng *xr.PRNG, w uint) ( fields []int, // FOR DEBUGGING ONLY keys [][]byte) { fieldCount := (1 << w) - 1 // we don't want the zero value fields = rng.Perm(fieldCount) // so 2^w distinct values for i := 0; i < len(fields); i++ { fields[i] += 1 } keyLen := uint((int(w)*fieldCount + 7) / 8) // in bytes, rounded up keyCount := uint(fieldCount) keys = make([][]byte, keyCount) for i := uint(0); i < keyCount; i++ { key := make([]byte, keyLen) // all zeroes if i != uint(0) { copy(key, keys[i-1]) } // OR the field into the appropriate byte(s) of the key bitOffset := w * i whichByte := bitOffset / uint(8) whichBit := bitOffset % uint(8) // lower half of the field key[whichByte] |= byte(fields[i] << whichBit) if whichBit+w >= 8 { key[whichByte+1] |= byte(fields[i] >> (8 - whichBit)) } keys[i] = key } return }
// Create an AES IV and key and an 8-byte salt, then encrypt these and // the proposed protocol version using the server's comms public key. func ClientEncryptHello(version1 uint32, ck *rsa.PublicKey, rng *xr.PRNG) ( cOneShot *AesSession, ciphertext []byte, err error) { if rng == nil { rng = xr.MakeSystemRNG() } vBytes := make([]byte, 4) vBytes[0] = byte(version1) vBytes[1] = byte(version1 >> 8) vBytes[2] = byte(version1 >> 16) vBytes[3] = byte(version1 >> 24) // Generate 32-byte AES key, and 8-byte salt for the Hello salty := make([]byte, 2*aes.BlockSize+8+20) rng.NextBytes(salty) key1 := salty[:2*aes.BlockSize] // salt1 := salty[2*aes.BlockSize : 2*aes.BlockSize+8] oaep1 := salty[2*aes.BlockSize+8:] oaepSalt := bytes.NewBuffer(oaep1) sha := sha1.New() data := salty[:2*aes.BlockSize+8] // contains key1,salt1 data = append(data, vBytes...) // ... plus preferred protocol version ciphertext, err = rsa.EncryptOAEP(sha, oaepSalt, ck, data, nil) if err == nil { cOneShot, err = NewAesSession(key1, rng) } return }
func (s *XLSuite) makeHostAndKeys(c *C, rng *xr.PRNG) ( n *xn.Node, ckPriv, skPriv *rsa.PrivateKey) { // XXX names may not be unique name := rng.NextFileName(6) for { first := string(name[0]) if !strings.Contains(first, "0123456789") && !strings.Contains(name, "-") { break } name = rng.NextFileName(6) } id := s.makeANodeID(c, rng) lfs := "tmp/" + hex.EncodeToString(id.Value()) ckPriv = s.makeAnRSAKey(c) skPriv = s.makeAnRSAKey(c) n, err2 := xn.New(name, id, lfs, ckPriv, skPriv, nil, nil, nil) c.Assert(err2, IsNil) c.Assert(n, Not(IsNil)) c.Assert(name, Equals, n.GetName()) actualID := n.GetNodeID() c.Assert(true, Equals, id.Equal(actualID)) // s.doKeyTests(c, n, rng) c.Assert(0, Equals, (*n).SizePeers()) c.Assert(0, Equals, (*n).SizeOverlays()) c.Assert(0, Equals, n.SizeConnections()) c.Assert(lfs, Equals, n.GetLFS()) return n, ckPriv, skPriv }
func (s *XLSuite) doTestParser(c *C, rng *xr.PRNG) { name := s.getAName(rng) a := rng.Intn(256) b := rng.Intn(256) _c := rng.Intn(256) d := rng.Intn(256) bits := rng.Intn(33) aRange := fmt.Sprintf("%d.%d.%d.%d/%d", a, b, _c, d, bits) transport := "tcp" cost := float32(rng.Intn(300)) / 100.0 ar, err := NewCIDRAddrRange(aRange) c.Assert(err, IsNil) o, err := NewIPOverlay(name, ar, transport, cost) c.Assert(err, IsNil) c.Assert(o, Not(IsNil)) c.Assert(name, Equals, o.Name()) // XXX ADDR RANGE MISSING c.Assert(transport, Equals, o.Transport()) c.Assert(float32(cost), Equals, o.Cost()) text := o.String() // DEBUG // fmt.Printf("serialized overlay is %s\n", text) // END o2, err := Parse(text) c.Assert(err, IsNil) c.Assert(text, Equals, o2.String()) }
// Make a RegCluster for test purposes. Cluster member names are guaranteed // to be unique but the name of the cluster itself may not be. // // THIS IS THE REGISTRY'S VIEW OF A CLUSTER func (s *XLSuite) makeARegCluster(c *C, rng *xr.PRNG, epCount, size uint32) ( rc *RegCluster) { var err error c.Assert(MIN_CLUSTER_SIZE <= size && size <= MAX_CLUSTER_SIZE, Equals, true) attrs := uint64(rng.Int63()) name := rng.NextFileName(8) // no guarantee of uniqueness id := s.makeANodeID(c, rng) rc, err = NewRegCluster(name, id, attrs, size, epCount) c.Assert(err, IsNil) for count := uint32(0); count < size; count++ { cm := s.makeAClientInfo(c, rng, epCount) for { if _, ok := rc.MembersByName[cm.GetName()]; ok { // name is in use, so try again cm = s.makeAClientInfo(c, rng, epCount) } else { err = rc.AddMember(cm) c.Assert(err, IsNil) break } } } return }
func doTestSimpleTreeConstructor(c *C, rng *xr.PRNG, usingSHA1 bool) { name := rng.NextFileName(8) tree := NewNLHTree(name, usingSHA1) c.Assert(tree.name, Equals, name) c.Assert(tree.usingSHA1, Equals, usingSHA1) c.Assert(len(tree.nodes), Equals, 0) }
// Return an initialized and tested host, with a NodeID, ckPriv, // and skPriv. OpenAcc() is not called and so any acceptors are not open. func (s *XLSuite) makeHost(c *C, rng *xr.PRNG) *Node { // XXX names may not be unique name := rng.NextFileName(6) for { first := string(name[0]) if !strings.Contains(first, "0123456789") && !strings.Contains(name, "-") { break } name = rng.NextFileName(6) } id, err := makeNodeID(rng) c.Assert(err, Equals, nil) c.Assert(id, Not(IsNil)) lfs := "tmp/" + hex.EncodeToString(id.Value()) n, err := NewNew(name, id, lfs) c.Assert(err, IsNil) c.Assert(n, Not(IsNil)) c.Assert(name, Equals, n.GetName()) actualID := n.GetNodeID() c.Assert(true, Equals, id.Equal(actualID)) s.doKeyTests(c, n, rng) c.Assert(0, Equals, (*n).SizePeers()) c.Assert(0, Equals, (*n).SizeOverlays()) c.Assert(0, Equals, n.SizeConnections()) c.Assert(lfs, Equals, n.GetLFS()) return n }
// Make a message (or reply) of up to 16 AES blocks in size and stuff // it with random bytes. Return the message with PKCS7-padded appended. // func (s *XLSuite) MakeAMsg(c *C, rng *xr.PRNG) ( msg []byte, msgLen int) { msgLen = 2 + rng.Intn(16*aes.BlockSize-2) msg = make([]byte, msgLen) rng.NextBytes(msg) return }
func doTestConstructor(c *C, rng *xr.PRNG, usingSHA1 bool) { name := rng.NextFileName(8) b := NewNLHBase(name, usingSHA1) c.Assert(b.Name(), Equals, name) c.Assert(b.UsingSHA1(), Equals, usingSHA1) root := b.Root() ct := b.CurTree() c.Assert(root.Name(), Equals, ct.Name()) }
func (s *XLSuite) getTwoUniqueDirectoryNames(c *C, rng *xr.PRNG) ( string, string) { dirName1 := rng.NextFileName(MAX_NAME_LEN) dirName2 := rng.NextFileName(MAX_NAME_LEN) for dirName2 == dirName1 { dirName2 = rng.NextFileName(MAX_NAME_LEN) } return dirName1, dirName2 }
func (s *XLSuite) getAName(rng *xr.PRNG) (name string) { name = string(rng.NextFileName(8)) for { first := string(name[0]) if !strings.ContainsAny(name, "-_.") && !strings.ContainsAny(first, "0123456789") { break } name = string(rng.NextFileName(8)) } return }
func makeNodeID(rng *xr.PRNG) (*xi.NodeID, error) { var buffer []byte // quasi-random choice, whether to use an SHA1 or SHA3 nodeID if rng.NextBoolean() { buffer = make([]byte, xu.SHA1_BIN_LEN) } else { buffer = make([]byte, xu.SHA3_BIN_LEN) } rng.NextBytes(buffer) return xi.NewNodeID(buffer) }
func getTwoUniqueDirectoryNames(c *C, rng *xr.PRNG) (dirName1, dirName2 string) { dirName1 = rng.NextFileName(8) dirName2 = dirName1 for dirName2 == dirName1 { dirName2 = rng.NextFileName(8) } c.Assert(len(dirName1) > 0, Equals, true) c.Assert(len(dirName2) > 0, Equals, true) c.Assert(dirName1 != dirName2, Equals, true) return }
func makeOneNamedTestDirectory(c *C, rng *xr.PRNG, name string, depth, width int) (dirPath string) { dirPath = fmt.Sprintf("tmp/%s", name) if _, err := os.Stat(dirPath); err == nil { err = os.RemoveAll(dirPath) c.Assert(err, IsNil) } // maxLen, minLen of files (bytes) rng.NextDataDir(dirPath, depth, width, 4096, 32) return }
func (s *XLSuite) makeANodeID(c *C, rng *xr.PRNG) (id *NodeID) { var length int if rng.NextBoolean() { length = xu.SHA1_BIN_LEN } else { length = xu.SHA2_BIN_LEN } data := make([]byte, length) rng.NextBytes(data) id, err := New(data) c.Assert(err, IsNil) return id }
func makeTwoTestDirectories(c *C, rng *xr.PRNG, depth, width int) ( dirName1, dirPath1, dirName2, dirPath2 string) { dirName1 = rng.NextFileName(8) dirPath1 = makeOneNamedTestDirectory(c, rng, dirName1, depth, width) dirName2 = dirName1 for dirName2 == dirName1 { dirName2 = rng.NextFileName(8) } dirPath2 = makeOneNamedTestDirectory(c, rng, dirName2, depth, width) return }
func (s *XLSuite) doTestKeySelector64(c *C, rng *xr.PRNG, usingSHA1 bool, m uint) { var v uint // length of byte array if usingSHA1 { // v = uint(20) // bytes } else { v = uint(32) } b := make([]byte, v) // value being inserted into filter k := uint((v * 8) / m) // number of hash functions bitSel := make([]byte, k) wordSel := make([]uint, k) // 2^6 is 64, number of bits in a uint64 wordsInFilter := 1 << (m - uint(6)) for i := uint(0); i < k; i++ { bitSel[i] = byte(rng.Intn(64)) wordSel[i] = uint(rng.Intn(wordsInFilter)) } // concatenate the key selectors at the front s.setBitOffsets(c, &b, bitSel) // append the word selectors s.setWordOffsets(c, &b, wordSel, m, k) // create an m,k filter filter, err := NewBloomSHA(m, k) c.Assert(err, IsNil) // verify that the expected bits are NOT set for i := uint(0); i < k; i++ { filterWord := filter.Filter[wordSel[i]] bitSelector := uint64(1) << bitSel[i] bitVal := filterWord & bitSelector c.Assert(bitVal == 0, Equals, true) } // insert the value b filter.Insert(b) // verify that all of the expected bits are set for i := uint(0); i < k; i++ { filterWord := filter.Filter[wordSel[i]] bitSelector := uint64(1) << bitSel[i] bitVal := filterWord & bitSelector c.Assert(bitVal == 0, Equals, false) } }
func doTestSimpleConstructor(c *C, rng *xr.PRNG, usingSHA1 bool) { var sha hash.Hash if usingSHA1 { sha = sha1.New() } else { sha = sha256.New() } name := rng.NextFileName(8) n := rng.SomeBytes(8) sha.Write(n) hash0 := sha.Sum(nil) leaf0, err := NewNLHLeaf(name, hash0) c.Assert(err, IsNil) c.Assert(name, Equals, leaf0.Name()) c.Assert(hash0, Equals, leaf0.BinHash()) name2 := name for name2 == name { name2 = rng.NextFileName(8) } n = rng.SomeBytes(8) sha.Write(n) hash1 := sha.Sum(nil) leaf1, err := NewNLHLeaf(name2, hash1) c.Assert(err, IsNil) c.Assert(name2, Equals, leaf1.Name()) c.Assert(hash1, Equals, leaf1.BinHash()) c.Assert(leaf0, Equals, leaf0) c.Assert(leaf1, Equals, leaf1) c.Assert(leaf0.Equal(leaf1), Equals, false) }
// Populate the K3 byte slices to be used for testing func (muc *MockUpaxClient) createData(rng *xr.PRNG, K3, L1, L2 int) ( err error) { muc.K3 = K3 muc.L1 = L1 muc.L2 = L2 muc.data = make([][]byte, K3) for i := 0; i < K3; i++ { length := L1 + rng.Intn(L2-L1+1) // so L1..L2 inclusive muc.data[i] = make([]byte, length) rng.NextBytes(muc.data[i]) } return }
func (s *XLSuite) makeAMemberInfo(c *C, rng *xr.PRNG) *xcl.MemberInfo { attrs := uint64(rng.Int63()) peer, err := xn.NewPeer( rng.NextFileName(8), s.makeANodeID(c, rng), &s.makeAnRSAKey(c).PublicKey, &s.makeAnRSAKey(c).PublicKey, nil, // overlays nil) // XXX CONNECTORS c.Assert(err, IsNil) return &xcl.MemberInfo{ Attrs: attrs, Peer: peer, } } // GEEP
func (s *XLSuite) makeOneNamedTestDirectory(c *C, rng *xr.PRNG, name string, depth, width int) string { name = strings.TrimSpace(name) dirPath := fmt.Sprintf("tmp/%s", name) if strings.Contains(dirPath, "..") { msg := fmt.Sprintf("directory name '%s' contains a double-dot\n", name) panic(msg) } err := os.RemoveAll(dirPath) c.Assert(err, IsNil) // max/minLen rng.NextDataDir(dirPath, depth, width, 32, 1) return dirPath }
func (s *XLSuite) makeContext(c *C, rng *xr.PRNG, size int) ( k, v []string, context *gc.Context) { var err error context = gc.NewNewContext() k = s.makeSymbolSet(c, rng, size) v = make([]string, size) for i := 0; i < size; i++ { value := rng.NextFileName(8) v[i] = value err = context.Bind(k[i], value) c.Assert(err, IsNil) } return k, v, context }
// Returns a slice of zero or more MiscItems. The slice must not contain // any S-S sequences (which are indistinguishable from a single S. func (s *XLSuite) createMiscItems(rng *xr.PRNG) (items []*MiscItem) { count := rng.Intn(4) // so 0 to 3 inclusive lastWasS := false for i := 0; i < count; i++ { item := s.createMiscItem(true, rng) // true = S ok lastWasS = s.IsS(item.body[0]) for item._type == MISC_S && lastWasS { item = s.createMiscItem(!lastWasS, rng) lastWasS = s.IsS(item.body[0]) } lastWasS = item._type == MISC_S items = append(items, item) } return }
func (s *XLSuite) uniqueKeyMaker(c *C, rng *xr.PRNG, w, keyCount, keyLen uint) ( rawKeys [][]byte, bKeys []BytesKey, hashcodes []uint64, values []interface{}) { maxCount := uint(1 << w) if keyCount > maxCount { msg := fmt.Sprintf( "too few bits in %d: cannot guarantee uniqueness of %d keys", w, keyCount) panic(msg) } flag := uint64(1 << w) mask := flag - 1 rawKeys = make([][]byte, keyCount) bKeys = make([]BytesKey, keyCount) hashcodes = make([]uint64, keyCount) values = make([]interface{}, keyCount) ndxMap := make(map[uint64]bool) // Build keyCount rawKeys of length keyLen, using the masked hashcode to // guarantee uniqueness. for i := uint(0); i < keyCount; i++ { var hc uint64 key := make([]byte, keyLen) for { rng.NextBytes(key) // fill with quasi-random values rawKeys[i] = key bKey, err := NewBytesKey(key) c.Assert(err, IsNil) c.Assert(bKey, NotNil) bKeys[i] = bKey hc = bKey.Hashcode() ndx := hc & mask _, ok := ndxMap[ndx] if !ok { ndxMap[ndx] = true break } } values[i] = &key hashcodes[i] = hc } return }
func (s *XLSuite) makeSymbolSet(c *C, rng *xr.PRNG, size int) (ss []string) { // make size unique names ss = make([]string, size) nameCache := make(map[string]string) for i := 0; i < size; i++ { name := rng.NextFileName(8) _, ok := nameCache[name] for ok { name = rng.NextFileName(8) _, ok = nameCache[name] } nameCache[name] = "" ss[i] = name } return // FOO }
func (s *XLSuite) doTestSHA(c *C, rng *xr.PRNG, whichSHA int) { var hash, fHash []byte var sHash string // name guaranteed to be unique length, pathToFile := rng.NextDataFile("tmp", 1024, 256) data, err := ioutil.ReadFile(pathToFile) c.Assert(err, IsNil) c.Assert(len(data), Equals, length) parts := strings.Split(pathToFile, "/") c.Assert(len(parts), Equals, 2) fileName := parts[1] switch whichSHA { case xu.USING_SHA1: sha := sha1.New() sha.Write(data) hash = sha.Sum(nil) fHash, err = SHA1File(pathToFile) case xu.USING_SHA2: sha := sha256.New() sha.Write(data) hash = sha.Sum(nil) fHash, err = SHA2File(pathToFile) case xu.USING_SHA3: sha := sha3.New256() sha.Write(data) hash = sha.Sum(nil) fHash, err = SHA3File(pathToFile) // XXX DEFAULT = ERROR } c.Assert(err, IsNil) c.Assert(bytes.Equal(hash, fHash), Equals, true) ml, err := CreateMerkleLeafFromFileSystem(pathToFile, fileName, whichSHA) c.Assert(err, IsNil) c.Assert(ml.Name(), Equals, fileName) c.Assert(bytes.Equal(ml.GetHash(), hash), Equals, true) c.Assert(ml.WhichSHA(), Equals, whichSHA) // TODO: test ToString _ = sHash // TODO }
func (s *XLSuite) makeAMemberInfo(c *C, rng *xr.PRNG) *xcl.MemberInfo { attrs := uint64(rng.Int63()) bn, err := xn.NewBaseNode( rng.NextFileName(8), s.makeANodeID(c, rng), &s.makeAnRSAKey(c).PublicKey, &s.makeAnRSAKey(c).PublicKey, nil) // overlays c.Assert(err, IsNil) asPeer := &xn.Peer{ BaseNode: *bn, } return &xcl.MemberInfo{ Attrs: attrs, Peer: asPeer, } }
func (s *XLSuite) makeAClientInfo(c *C, rng *xr.PRNG, epCount uint32) *ClientInfo { attrs := uint64(rng.Int63()) var myEnds []string for i := uint32(0); i < epCount; i++ { myEnds = append(myEnds, "127.0.0.1:0") } bn, err := xn.NewBaseNode( rng.NextFileName(8), s.makeANodeID(c, rng), &s.makeAnRSAKey(c).PublicKey, &s.makeAnRSAKey(c).PublicKey, nil) // overlays c.Assert(err, IsNil) return &ClientInfo{ Attrs: attrs, MyEnds: myEnds, BaseNode: *bn, } }
func setUpMB3(c *C, rng *xr.PRNG) ( filter *MappedBloomSHA, m, k uint, keys [][]byte, backingFile string) { m = 20 k = 8 keys = make([][]byte, 100) for i := 0; i < 100; i++ { keys[i] = make([]byte, 20) } backingFile = "tmp/" + rng.NextFileName(8) // make sure the file does not already exist found, err := xf.PathExists(backingFile) c.Assert(err, IsNil) for found { backingFile = "tmp/" + rng.NextFileName(8) found, err = xf.PathExists(backingFile) c.Assert(err, IsNil) } return }
// Returns a slice of zero or more Attributes. Attribute names must be // unique within the slice. func (s *XLSuite) createAttrValPairs(rng *xr.PRNG) (pairs []*AttrValPair) { count := rng.Intn(4) // so 0 to 3 inclusive var byName = make(map[string]*AttrValPair) for i := 0; i < count; i++ { var pair *AttrValPair for { pair = s.createAttrValPair(rng) // attr names must be unique; values need not be name := pair.Attr if _, ok := byName[name]; ok { continue } else { // it's not in the map, so add it byName[name] = pair break } } pairs = append(pairs, pair) } return }