//Verify checks res is codeward in the server. func Verify(res []byte, fnum int, key []byte, n int, loc []int) (bool, error) { p := &prf{key: key, fnum: fnum} for _, l := range loc { res[len(res)-1] ^= p.rand(l) } enc, err := reedsolomon.NewAN(nServerBlock-1, 1, p.perm()) if err != nil { log.Println(err) return false, err } data := make([][]byte, nServerBlock) for i := 0; i < nServerBlock; i++ { data[i] = make([]byte, 1) data[i][0] = res[i] } ok, err := enc.Verify(data) if err != nil { log.Println(err) return false, err } return ok, nil }
//Build builds shards for servers with reed solomon coding //and (255,1) redundant codes for each servers for challenge/response. func Build(m, n int, fname string) ([]string, []byte, error) { key := make([]byte, 32) if _, err := rand.Read(key); err != nil { log.Fatal(err) } prf := &prf{key: key} enc, err := reedsolomon.New(n, m) if err != nil { log.Println(err) return nil, nil, err } data := make([][]byte, m+n) rs, err := rmmap(fname) if err != nil { log.Println(err) return nil, nil, err } defer rs.Close() shardSize, err := size(rs.f, n) if err != nil { return nil, nil, err } serverBlockSize := blocks(shardSize, nServerBlock-1) ss := make([]*smap, m+n) name := parseName(fname) outfiles := make([]string, m+n) for i := 0; i < m+n; i++ { outfiles[i] = name.rename(i) ss[i], err = wmmap(outfiles[i], int64(serverBlockSize)*nServerBlock) if err != nil { log.Println(err) return nil, nil, err } data[i] = ss[i].bytes()[:shardSize] } defer func() { for i := 0; i < m+n; i++ { ss[i].Close() } }() for i := 0; i < n; i++ { end := (i + 1) * shardSize if end > len(rs.bytes()) { end = len(rs.bytes()) } copy(data[i], rs.bytes()[i*shardSize:end]) } if err != nil { log.Println(err) return nil, nil, err } if err = enc.Encode(data); err != nil { log.Println(err) return nil, nil, err } encServer, err := reedsolomon.NewAN(nServerBlock-1, 1, prf.perm()) if err != nil { log.Println(err) return nil, nil, err } for i := 0; i < m+n; i++ { prf.fnum = i if err := serverEncode(ss[i].bytes(), prf, serverBlockSize, encServer); err != nil { log.Println(err) return nil, nil, err } } return outfiles, key, err }